Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: samples/process.cc

Issue 12716010: Added a version of the v8::HandleScope constructor with an Isolate and use that consistently. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Feedback. Rebased Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « samples/lineprocessor.cc ('k') | samples/shell.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 static void Log(const char* event); 72 static void Log(const char* event);
73 }; 73 };
74 74
75 /** 75 /**
76 * An http request processor that is scriptable using JavaScript. 76 * An http request processor that is scriptable using JavaScript.
77 */ 77 */
78 class JsHttpRequestProcessor : public HttpRequestProcessor { 78 class JsHttpRequestProcessor : public HttpRequestProcessor {
79 public: 79 public:
80 // Creates a new processor that processes requests by invoking the 80 // Creates a new processor that processes requests by invoking the
81 // Process function of the JavaScript script given as an argument. 81 // Process function of the JavaScript script given as an argument.
82 explicit JsHttpRequestProcessor(Handle<String> script) : script_(script) { } 82 JsHttpRequestProcessor(Isolate* isolate, Handle<String> script)
83 : isolate_(isolate), script_(script) { }
83 virtual ~JsHttpRequestProcessor(); 84 virtual ~JsHttpRequestProcessor();
84 85
85 virtual bool Initialize(map<string, string>* opts, 86 virtual bool Initialize(map<string, string>* opts,
86 map<string, string>* output); 87 map<string, string>* output);
87 virtual bool Process(HttpRequest* req); 88 virtual bool Process(HttpRequest* req);
88 89
89 private: 90 private:
90 // Execute the script associated with this processor and extract the 91 // Execute the script associated with this processor and extract the
91 // Process function. Returns true if this succeeded, otherwise false. 92 // Process function. Returns true if this succeeded, otherwise false.
92 bool ExecuteScript(Handle<String> script); 93 bool ExecuteScript(Handle<String> script);
93 94
94 // Wrap the options and output map in a JavaScript objects and 95 // Wrap the options and output map in a JavaScript objects and
95 // install it in the global namespace as 'options' and 'output'. 96 // install it in the global namespace as 'options' and 'output'.
96 bool InstallMaps(map<string, string>* opts, map<string, string>* output); 97 bool InstallMaps(map<string, string>* opts, map<string, string>* output);
97 98
98 // Constructs the template that describes the JavaScript wrapper 99 // Constructs the template that describes the JavaScript wrapper
99 // type for requests. 100 // type for requests.
100 static Handle<ObjectTemplate> MakeRequestTemplate(); 101 static Handle<ObjectTemplate> MakeRequestTemplate(Isolate* isolate);
101 static Handle<ObjectTemplate> MakeMapTemplate(); 102 static Handle<ObjectTemplate> MakeMapTemplate(Isolate* isolate);
102 103
103 // Callbacks that access the individual fields of request objects. 104 // Callbacks that access the individual fields of request objects.
104 static Handle<Value> GetPath(Local<String> name, const AccessorInfo& info); 105 static Handle<Value> GetPath(Local<String> name, const AccessorInfo& info);
105 static Handle<Value> GetReferrer(Local<String> name, 106 static Handle<Value> GetReferrer(Local<String> name,
106 const AccessorInfo& info); 107 const AccessorInfo& info);
107 static Handle<Value> GetHost(Local<String> name, const AccessorInfo& info); 108 static Handle<Value> GetHost(Local<String> name, const AccessorInfo& info);
108 static Handle<Value> GetUserAgent(Local<String> name, 109 static Handle<Value> GetUserAgent(Local<String> name,
109 const AccessorInfo& info); 110 const AccessorInfo& info);
110 111
111 // Callbacks that access maps 112 // Callbacks that access maps
112 static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info); 113 static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info);
113 static Handle<Value> MapSet(Local<String> name, 114 static Handle<Value> MapSet(Local<String> name,
114 Local<Value> value, 115 Local<Value> value,
115 const AccessorInfo& info); 116 const AccessorInfo& info);
116 117
117 // Utility methods for wrapping C++ objects as JavaScript objects, 118 // Utility methods for wrapping C++ objects as JavaScript objects,
118 // and going back again. 119 // and going back again.
119 Handle<Object> WrapMap(map<string, string>* obj); 120 Handle<Object> WrapMap(map<string, string>* obj);
120 static map<string, string>* UnwrapMap(Handle<Object> obj); 121 static map<string, string>* UnwrapMap(Handle<Object> obj);
121 Handle<Object> WrapRequest(HttpRequest* obj); 122 Handle<Object> WrapRequest(HttpRequest* obj);
122 static HttpRequest* UnwrapRequest(Handle<Object> obj); 123 static HttpRequest* UnwrapRequest(Handle<Object> obj);
123 124
124 Isolate* GetIsolate() { return context_->GetIsolate(); } 125 Isolate* GetIsolate() { return isolate_; }
125 126
127 Isolate* isolate_;
126 Handle<String> script_; 128 Handle<String> script_;
127 Persistent<Context> context_; 129 Persistent<Context> context_;
128 Persistent<Function> process_; 130 Persistent<Function> process_;
129 static Persistent<ObjectTemplate> request_template_; 131 static Persistent<ObjectTemplate> request_template_;
130 static Persistent<ObjectTemplate> map_template_; 132 static Persistent<ObjectTemplate> map_template_;
131 }; 133 };
132 134
133 // ------------------------- 135 // -------------------------
134 // --- P r o c e s s o r --- 136 // --- P r o c e s s o r ---
135 // ------------------------- 137 // -------------------------
136 138
137 139
138 static Handle<Value> LogCallback(const Arguments& args) { 140 static Handle<Value> LogCallback(const Arguments& args) {
139 if (args.Length() < 1) return v8::Undefined(); 141 if (args.Length() < 1) return Undefined();
140 HandleScope scope; 142 HandleScope scope(args.GetIsolate());
141 Handle<Value> arg = args[0]; 143 Handle<Value> arg = args[0];
142 String::Utf8Value value(arg); 144 String::Utf8Value value(arg);
143 HttpRequestProcessor::Log(*value); 145 HttpRequestProcessor::Log(*value);
144 return v8::Undefined(); 146 return Undefined();
145 } 147 }
146 148
147 149
148 // Execute the script and fetch the Process method. 150 // Execute the script and fetch the Process method.
149 bool JsHttpRequestProcessor::Initialize(map<string, string>* opts, 151 bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
150 map<string, string>* output) { 152 map<string, string>* output) {
151 // Create a handle scope to hold the temporary references. 153 // Create a handle scope to hold the temporary references.
152 HandleScope handle_scope; 154 HandleScope handle_scope(GetIsolate());
153 155
154 // Create a template for the global object where we set the 156 // Create a template for the global object where we set the
155 // built-in global functions. 157 // built-in global functions.
156 Handle<ObjectTemplate> global = ObjectTemplate::New(); 158 Handle<ObjectTemplate> global = ObjectTemplate::New();
157 global->Set(String::New("log"), FunctionTemplate::New(LogCallback)); 159 global->Set(String::New("log"), FunctionTemplate::New(LogCallback));
158 160
159 // Each processor gets its own context so different processors don't 161 // Each processor gets its own context so different processors don't
160 // affect each other. Context::New returns a persistent handle which 162 // affect each other. Context::New returns a persistent handle which
161 // is what we need for the reference to remain after we return from 163 // is what we need for the reference to remain after we return from
162 // this method. That persistent handle has to be disposed in the 164 // this method. That persistent handle has to be disposed in the
(...skipping 27 matching lines...) Expand all
190 // Store the function in a Persistent handle, since we also want 192 // Store the function in a Persistent handle, since we also want
191 // that to remain after this call returns 193 // that to remain after this call returns
192 process_ = Persistent<Function>::New(GetIsolate(), process_fun); 194 process_ = Persistent<Function>::New(GetIsolate(), process_fun);
193 195
194 // All done; all went well 196 // All done; all went well
195 return true; 197 return true;
196 } 198 }
197 199
198 200
199 bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { 201 bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
200 HandleScope handle_scope; 202 HandleScope handle_scope(GetIsolate());
201 203
202 // We're just about to compile the script; set up an error handler to 204 // We're just about to compile the script; set up an error handler to
203 // catch any exceptions the script might throw. 205 // catch any exceptions the script might throw.
204 TryCatch try_catch; 206 TryCatch try_catch;
205 207
206 // Compile the script and check for errors. 208 // Compile the script and check for errors.
207 Handle<Script> compiled_script = Script::Compile(script); 209 Handle<Script> compiled_script = Script::Compile(script);
208 if (compiled_script.IsEmpty()) { 210 if (compiled_script.IsEmpty()) {
209 String::Utf8Value error(try_catch.Exception()); 211 String::Utf8Value error(try_catch.Exception());
210 Log(*error); 212 Log(*error);
211 // The script failed to compile; bail out. 213 // The script failed to compile; bail out.
212 return false; 214 return false;
213 } 215 }
214 216
215 // Run the script! 217 // Run the script!
216 Handle<Value> result = compiled_script->Run(); 218 Handle<Value> result = compiled_script->Run();
217 if (result.IsEmpty()) { 219 if (result.IsEmpty()) {
218 // The TryCatch above is still in effect and will have caught the error. 220 // The TryCatch above is still in effect and will have caught the error.
219 String::Utf8Value error(try_catch.Exception()); 221 String::Utf8Value error(try_catch.Exception());
220 Log(*error); 222 Log(*error);
221 // Running the script failed; bail out. 223 // Running the script failed; bail out.
222 return false; 224 return false;
223 } 225 }
224 return true; 226 return true;
225 } 227 }
226 228
227 229
228 bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts, 230 bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts,
229 map<string, string>* output) { 231 map<string, string>* output) {
230 HandleScope handle_scope; 232 HandleScope handle_scope(GetIsolate());
231 233
232 // Wrap the map object in a JavaScript wrapper 234 // Wrap the map object in a JavaScript wrapper
233 Handle<Object> opts_obj = WrapMap(opts); 235 Handle<Object> opts_obj = WrapMap(opts);
234 236
235 // Set the options object as a property on the global object. 237 // Set the options object as a property on the global object.
236 context_->Global()->Set(String::New("options"), opts_obj); 238 context_->Global()->Set(String::New("options"), opts_obj);
237 239
238 Handle<Object> output_obj = WrapMap(output); 240 Handle<Object> output_obj = WrapMap(output);
239 context_->Global()->Set(String::New("output"), output_obj); 241 context_->Global()->Set(String::New("output"), output_obj);
240 242
241 return true; 243 return true;
242 } 244 }
243 245
244 246
245 bool JsHttpRequestProcessor::Process(HttpRequest* request) { 247 bool JsHttpRequestProcessor::Process(HttpRequest* request) {
246 // Create a handle scope to keep the temporary object references. 248 // Create a handle scope to keep the temporary object references.
247 HandleScope handle_scope; 249 HandleScope handle_scope(GetIsolate());
248 250
249 // Enter this processor's context so all the remaining operations 251 // Enter this processor's context so all the remaining operations
250 // take place there 252 // take place there
251 Context::Scope context_scope(context_); 253 Context::Scope context_scope(context_);
252 254
253 // Wrap the C++ request object in a JavaScript wrapper 255 // Wrap the C++ request object in a JavaScript wrapper
254 Handle<Object> request_obj = WrapRequest(request); 256 Handle<Object> request_obj = WrapRequest(request);
255 257
256 // Set up an exception handler before calling the Process function 258 // Set up an exception handler before calling the Process function
257 TryCatch try_catch; 259 TryCatch try_catch;
(...skipping 10 matching lines...) Expand all
268 } else { 270 } else {
269 return true; 271 return true;
270 } 272 }
271 } 273 }
272 274
273 275
274 JsHttpRequestProcessor::~JsHttpRequestProcessor() { 276 JsHttpRequestProcessor::~JsHttpRequestProcessor() {
275 // Dispose the persistent handles. When noone else has any 277 // Dispose the persistent handles. When noone else has any
276 // references to the objects stored in the handles they will be 278 // references to the objects stored in the handles they will be
277 // automatically reclaimed. 279 // automatically reclaimed.
278 v8::Isolate* isolate = GetIsolate(); 280 Isolate* isolate = GetIsolate();
279 context_.Dispose(isolate); 281 context_.Dispose(isolate);
280 process_.Dispose(isolate); 282 process_.Dispose(isolate);
281 } 283 }
282 284
283 285
284 Persistent<ObjectTemplate> JsHttpRequestProcessor::request_template_; 286 Persistent<ObjectTemplate> JsHttpRequestProcessor::request_template_;
285 Persistent<ObjectTemplate> JsHttpRequestProcessor::map_template_; 287 Persistent<ObjectTemplate> JsHttpRequestProcessor::map_template_;
286 288
287 289
288 // ----------------------------------- 290 // -----------------------------------
289 // --- A c c e s s i n g M a p s --- 291 // --- A c c e s s i n g M a p s ---
290 // ----------------------------------- 292 // -----------------------------------
291 293
292 // Utility function that wraps a C++ http request object in a 294 // Utility function that wraps a C++ http request object in a
293 // JavaScript object. 295 // JavaScript object.
294 Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) { 296 Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) {
295 // Handle scope for temporary handles. 297 // Handle scope for temporary handles.
296 HandleScope handle_scope; 298 HandleScope handle_scope(GetIsolate());
297 299
298 // Fetch the template for creating JavaScript map wrappers. 300 // Fetch the template for creating JavaScript map wrappers.
299 // It only has to be created once, which we do on demand. 301 // It only has to be created once, which we do on demand.
300 if (map_template_.IsEmpty()) { 302 if (map_template_.IsEmpty()) {
301 Handle<ObjectTemplate> raw_template = MakeMapTemplate(); 303 Handle<ObjectTemplate> raw_template = MakeMapTemplate(GetIsolate());
302 map_template_ = Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); 304 map_template_ = Persistent<ObjectTemplate>::New(GetIsolate(), raw_template);
303 } 305 }
304 Handle<ObjectTemplate> templ = map_template_; 306 Handle<ObjectTemplate> templ = map_template_;
305 307
306 // Create an empty map wrapper. 308 // Create an empty map wrapper.
307 Handle<Object> result = templ->NewInstance(); 309 Handle<Object> result = templ->NewInstance();
308 310
309 // Wrap the raw C++ pointer in an External so it can be referenced 311 // Wrap the raw C++ pointer in an External so it can be referenced
310 // from within JavaScript. 312 // from within JavaScript.
311 Handle<External> map_ptr = External::New(obj); 313 Handle<External> map_ptr = External::New(obj);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 string value = ObjectToString(value_obj); 371 string value = ObjectToString(value_obj);
370 372
371 // Update the map. 373 // Update the map.
372 (*obj)[key] = value; 374 (*obj)[key] = value;
373 375
374 // Return the value; any non-empty handle will work. 376 // Return the value; any non-empty handle will work.
375 return value_obj; 377 return value_obj;
376 } 378 }
377 379
378 380
379 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate() { 381 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate(
380 HandleScope handle_scope; 382 Isolate* isolate) {
383 HandleScope handle_scope(isolate);
381 384
382 Handle<ObjectTemplate> result = ObjectTemplate::New(); 385 Handle<ObjectTemplate> result = ObjectTemplate::New();
383 result->SetInternalFieldCount(1); 386 result->SetInternalFieldCount(1);
384 result->SetNamedPropertyHandler(MapGet, MapSet); 387 result->SetNamedPropertyHandler(MapGet, MapSet);
385 388
386 // Again, return the result through the current handle scope. 389 // Again, return the result through the current handle scope.
387 return handle_scope.Close(result); 390 return handle_scope.Close(result);
388 } 391 }
389 392
390 393
391 // ------------------------------------------- 394 // -------------------------------------------
392 // --- A c c e s s i n g R e q u e s t s --- 395 // --- A c c e s s i n g R e q u e s t s ---
393 // ------------------------------------------- 396 // -------------------------------------------
394 397
395 /** 398 /**
396 * Utility function that wraps a C++ http request object in a 399 * Utility function that wraps a C++ http request object in a
397 * JavaScript object. 400 * JavaScript object.
398 */ 401 */
399 Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) { 402 Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) {
400 // Handle scope for temporary handles. 403 // Handle scope for temporary handles.
401 HandleScope handle_scope; 404 HandleScope handle_scope(GetIsolate());
402 405
403 // Fetch the template for creating JavaScript http request wrappers. 406 // Fetch the template for creating JavaScript http request wrappers.
404 // It only has to be created once, which we do on demand. 407 // It only has to be created once, which we do on demand.
405 if (request_template_.IsEmpty()) { 408 if (request_template_.IsEmpty()) {
406 Handle<ObjectTemplate> raw_template = MakeRequestTemplate(); 409 Handle<ObjectTemplate> raw_template = MakeRequestTemplate(GetIsolate());
407 request_template_ = 410 request_template_ =
408 Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); 411 Persistent<ObjectTemplate>::New(GetIsolate(), raw_template);
409 } 412 }
410 Handle<ObjectTemplate> templ = request_template_; 413 Handle<ObjectTemplate> templ = request_template_;
411 414
412 // Create an empty http request wrapper. 415 // Create an empty http request wrapper.
413 Handle<Object> result = templ->NewInstance(); 416 Handle<Object> result = templ->NewInstance();
414 417
415 // Wrap the raw C++ pointer in an External so it can be referenced 418 // Wrap the raw C++ pointer in an External so it can be referenced
416 // from within JavaScript. 419 // from within JavaScript.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 471
469 472
470 Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name, 473 Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name,
471 const AccessorInfo& info) { 474 const AccessorInfo& info) {
472 HttpRequest* request = UnwrapRequest(info.Holder()); 475 HttpRequest* request = UnwrapRequest(info.Holder());
473 const string& path = request->UserAgent(); 476 const string& path = request->UserAgent();
474 return String::New(path.c_str(), static_cast<int>(path.length())); 477 return String::New(path.c_str(), static_cast<int>(path.length()));
475 } 478 }
476 479
477 480
478 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate() { 481 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate(
479 HandleScope handle_scope; 482 Isolate* isolate) {
483 HandleScope handle_scope(isolate);
480 484
481 Handle<ObjectTemplate> result = ObjectTemplate::New(); 485 Handle<ObjectTemplate> result = ObjectTemplate::New();
482 result->SetInternalFieldCount(1); 486 result->SetInternalFieldCount(1);
483 487
484 // Add accessors for each of the fields of the request. 488 // Add accessors for each of the fields of the request.
485 result->SetAccessor(String::NewSymbol("path"), GetPath); 489 result->SetAccessor(String::NewSymbol("path"), GetPath);
486 result->SetAccessor(String::NewSymbol("referrer"), GetReferrer); 490 result->SetAccessor(String::NewSymbol("referrer"), GetReferrer);
487 result->SetAccessor(String::NewSymbol("host"), GetHost); 491 result->SetAccessor(String::NewSymbol("host"), GetHost);
488 result->SetAccessor(String::NewSymbol("userAgent"), GetUserAgent); 492 result->SetAccessor(String::NewSymbol("userAgent"), GetUserAgent);
489 493
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 605
602 606
603 int main(int argc, char* argv[]) { 607 int main(int argc, char* argv[]) {
604 map<string, string> options; 608 map<string, string> options;
605 string file; 609 string file;
606 ParseOptions(argc, argv, options, &file); 610 ParseOptions(argc, argv, options, &file);
607 if (file.empty()) { 611 if (file.empty()) {
608 fprintf(stderr, "No script was specified.\n"); 612 fprintf(stderr, "No script was specified.\n");
609 return 1; 613 return 1;
610 } 614 }
611 HandleScope scope; 615 Isolate* isolate = Isolate::GetCurrent();
616 HandleScope scope(isolate);
612 Handle<String> source = ReadFile(file); 617 Handle<String> source = ReadFile(file);
613 if (source.IsEmpty()) { 618 if (source.IsEmpty()) {
614 fprintf(stderr, "Error reading '%s'.\n", file.c_str()); 619 fprintf(stderr, "Error reading '%s'.\n", file.c_str());
615 return 1; 620 return 1;
616 } 621 }
617 JsHttpRequestProcessor processor(source); 622 JsHttpRequestProcessor processor(isolate, source);
618 map<string, string> output; 623 map<string, string> output;
619 if (!processor.Initialize(&options, &output)) { 624 if (!processor.Initialize(&options, &output)) {
620 fprintf(stderr, "Error initializing processor.\n"); 625 fprintf(stderr, "Error initializing processor.\n");
621 return 1; 626 return 1;
622 } 627 }
623 if (!ProcessEntries(&processor, kSampleSize, kSampleRequests)) 628 if (!ProcessEntries(&processor, kSampleSize, kSampleRequests))
624 return 1; 629 return 1;
625 PrintMap(&output); 630 PrintMap(&output);
626 } 631 }
OLDNEW
« no previous file with comments | « samples/lineprocessor.cc ('k') | samples/shell.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698