@@ -63,6 +63,46 @@ struct PluginBase {
6363 std::string log_prefix_;
6464};
6565
66+ struct BufferBase : public BufferInterface {
67+ BufferBase () = default ;
68+ ~BufferBase () override = default ;
69+
70+ // BufferInterface
71+ size_t size () const override {
72+ if (owned_data_) {
73+ return owned_data_size_;
74+ }
75+ return data_.size ();
76+ }
77+ WasmResult copyTo (WasmBase *wasm, size_t start, size_t length, uint64_t ptr_ptr,
78+ uint64_t size_ptr) const override ;
79+ WasmResult copyFrom (size_t /* start */ , size_t /* length */ , string_view /* data */ ) override {
80+ // Setting a string buffer not supported (no use case).
81+ return WasmResult::BadArgument;
82+ }
83+
84+ virtual void clear () {
85+ data_ = " " ;
86+ owned_data_ = nullptr ;
87+ }
88+ BufferBase *set (string_view data) {
89+ clear ();
90+ data_ = data;
91+ return this ;
92+ }
93+ BufferBase *set (std::unique_ptr<char []> owned_data, uint32_t owned_data_size) {
94+ clear ();
95+ owned_data_ = std::move (owned_data);
96+ owned_data_size_ = owned_data_size;
97+ return this ;
98+ }
99+
100+ protected:
101+ string_view data_;
102+ std::unique_ptr<char []> owned_data_;
103+ uint32_t owned_data_size_;
104+ };
105+
66106/* *
67107 * ContextBase is the interface between the VM host and the VM. It has several uses:
68108 *
@@ -94,7 +134,7 @@ class ContextBase : public RootInterface,
94134 ContextBase (); // Testing.
95135 ContextBase (WasmBase *wasm); // Vm Context.
96136 ContextBase (WasmBase *wasm, std::shared_ptr<PluginBase> plugin); // Root Context.
97- ContextBase (WasmBase *wasm, uint32_t root_context_id ,
137+ ContextBase (WasmBase *wasm, uint32_t parent_context_id ,
98138 std::shared_ptr<PluginBase> plugin); // Stream context.
99139 virtual ~ContextBase ();
100140
@@ -103,8 +143,17 @@ class ContextBase : public RootInterface,
103143 // The VM Context used for calling "malloc" has an id_ == 0.
104144 bool isVmContext () const { return id_ == 0 ; }
105145 // Root Contexts have the VM Context as a parent.
106- bool isRootContext () const { return root_context_id_ == 0 ; }
107- ContextBase *root_context () const { return root_context_; }
146+ bool isRootContext () const { return parent_context_id_ == 0 ; }
147+ ContextBase *parent_context () const { return parent_context_; }
148+ ContextBase *root_context () const {
149+ const ContextBase *previous = this ;
150+ ContextBase *parent = parent_context_;
151+ while (parent != previous) {
152+ previous = parent;
153+ parent = parent->parent_context_ ;
154+ }
155+ return parent;
156+ }
108157 string_view root_id () const { return isRootContext () ? root_id_ : plugin_->root_id_ ; }
109158 string_view log_prefix () const {
110159 return isRootContext () ? root_log_prefix_ : plugin_->log_prefix ();
@@ -121,10 +170,11 @@ class ContextBase : public RootInterface,
121170 */
122171
123172 // Context
124- void onCreate (uint32_t parent_context_id ) override ;
173+ void onCreate () override ;
125174 bool onDone () override ;
126175 void onLog () override ;
127176 void onDelete () override ;
177+ void onForeignFunction (uint32_t foreign_function_id, uint32_t data_size) override ;
128178
129179 // Root
130180 bool onStart (std::shared_ptr<PluginBase> plugin) override ;
@@ -173,10 +223,6 @@ class ContextBase : public RootInterface,
173223 WasmResult log (uint32_t /* level */ , string_view /* message */ ) override {
174224 return unimplemented ();
175225 }
176- WasmResult setTimerPeriod (std::chrono::milliseconds /* period */ ,
177- uint32_t * /* timer_token_ptr */ ) override {
178- return unimplemented ();
179- }
180226 uint64_t getCurrentTimeNanoseconds () override {
181227 struct timespec tpe;
182228 clock_gettime (CLOCK_REALTIME, &tpe);
@@ -189,6 +235,7 @@ class ContextBase : public RootInterface,
189235 unimplemented ();
190236 return std::make_pair (1 , " unimplmemented" );
191237 }
238+ WasmResult setTimerPeriod (std::chrono::milliseconds period, uint32_t *timer_token_ptr) override ;
192239
193240 // Buffer
194241 BufferInterface *getBuffer (WasmBufferType /* type */ ) override {
@@ -316,15 +363,24 @@ class ContextBase : public RootInterface,
316363
317364 WasmBase *wasm_{nullptr };
318365 uint32_t id_{0 };
319- uint32_t root_context_id_ {0 }; // 0 for roots and the general context.
320- ContextBase *root_context_ {nullptr }; // set in all contexts.
321- std::string root_id_; // set only in root context.
322- std::string root_log_prefix_; // set only in root context.
366+ uint32_t parent_context_id_ {0 }; // 0 for roots and the general context.
367+ ContextBase *parent_context_ {nullptr }; // set in all contexts.
368+ std::string root_id_; // set only in root context.
369+ std::string root_log_prefix_; // set only in root context.
323370 std::shared_ptr<PluginBase> plugin_;
324371 bool in_vm_context_created_ = false ;
325372 bool destroyed_ = false ;
326373};
327374
375+ class DeferAfterCallActions {
376+ public:
377+ DeferAfterCallActions (ContextBase *context) : wasm_(context->wasm ()) {}
378+ ~DeferAfterCallActions ();
379+
380+ private:
381+ WasmBase *const wasm_;
382+ };
383+
328384uint32_t resolveQueueForTest (string_view vm_id, string_view queue_name);
329385
330386} // namespace proxy_wasm
0 commit comments