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

Side by Side Diff: webkit/port/bindings/v8/NPV8Object.cpp

Issue 141022: Delete the upstreamed files: V8NPUtils.h V8NPUtils.cpp NPV8Object.h NPV8Object.cpp. (Closed)
Patch Set: rebased on tip of tree Created 11 years, 5 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
« no previous file with comments | « webkit/port/bindings/v8/NPV8Object.h ('k') | webkit/port/bindings/v8/V8NPUtils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2007-2009 Google, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28
29 #include <stdio.h>
30
31 #define max max
32 #define min min
33 #include <v8.h>
34 #include "NPV8Object.h"
35 #include "ChromiumBridge.h"
36 #include "Frame.h"
37 #include "bindings/npruntime.h"
38 #include "npruntime_priv.h"
39 #include "PlatformString.h"
40 #include "ScriptController.h"
41 #include "V8CustomBinding.h"
42 #include "V8Helpers.h"
43 #include "V8NPUtils.h"
44 #include "v8_proxy.h"
45 #include "DOMWindow.h"
46
47 using WebCore::toV8Context;
48 using WebCore::toV8Proxy;
49 using WebCore::V8ClassIndex;
50 using WebCore::V8Custom;
51 using WebCore::V8Proxy;
52
53 // FIXME(mbelshe): comments on why use malloc and free.
54 static NPObject* AllocV8NPObject(NPP, NPClass*)
55 {
56 return static_cast<NPObject*>(malloc(sizeof(V8NPObject)));
57 }
58
59 static void FreeV8NPObject(NPObject* npobj)
60 {
61 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
62 #ifndef NDEBUG
63 V8Proxy::UnregisterGlobalHandle(object, object->v8Object);
64 #endif
65 object->v8Object.Dispose();
66 free(object);
67 }
68
69 static v8::Handle<v8::Value>* listFromVariantArgs(const NPVariant* args,
70 uint32_t argCount,
71 NPObject *owner)
72 {
73 v8::Handle<v8::Value>* argv = new v8::Handle<v8::Value>[argCount];
74 for (uint32_t index = 0; index < argCount; index++) {
75 const NPVariant *arg = &args[index];
76 argv[index] = convertNPVariantToV8Object(arg, owner);
77 }
78 return argv;
79 }
80
81 // Create an identifier (null terminated utf8 char*) from the NPIdentifier.
82 static v8::Local<v8::String> NPIdentifierToV8Identifier(NPIdentifier name)
83 {
84 PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(name);
85 if (identifier->isString)
86 return v8::String::New(static_cast<const char *>(identifier->value.strin g));
87
88 char buf[32];
89 sprintf(buf, "%d", identifier->value.number);
90 return v8::String::New(buf);
91 }
92
93 static NPClass V8NPObjectClass = { NP_CLASS_STRUCT_VERSION,
94 AllocV8NPObject,
95 FreeV8NPObject,
96 0, 0, 0, 0, 0, 0, 0, 0, 0 };
97
98 // NPAPI's npruntime functions
99 NPClass* npScriptObjectClass = &V8NPObjectClass;
100
101 NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, WebCore ::DOMWindow* root)
102 {
103 // Check to see if this object is already wrapped.
104 if (object->InternalFieldCount() == V8Custom::kNPObjectInternalFieldCount &&
105 object->GetInternalField(V8Custom::kDOMWrapperTypeIndex)->IsNumber() &&
106 object->GetInternalField(V8Custom::kDOMWrapperTypeIndex)->Uint32Value() == V8ClassIndex::NPOBJECT) {
107
108 NPObject* rv = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, object);
109 NPN_RetainObject(rv);
110 return rv;
111 }
112
113 V8NPObject* obj = reinterpret_cast<V8NPObject*>(NPN_CreateObject(npp, &V8NPO bjectClass));
114 obj->v8Object = v8::Persistent<v8::Object>::New(object);
115 #ifndef NDEBUG
116 V8Proxy::RegisterGlobalHandle(WebCore::NPOBJECT, obj, obj->v8Object);
117 #endif
118 obj->rootObject = root;
119 return reinterpret_cast<NPObject*>(obj);
120 }
121
122 bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
123 const NPVariant *args, uint32_t argCount, NPVariant *result)
124 {
125 if (!npobj)
126 return false;
127
128 if (npobj->_class == npScriptObjectClass) {
129 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
130
131 PrivateIdentifier *identifier = static_cast<PrivateIdentifier*>(methodNa me);
132 if (!identifier->isString)
133 return false;
134
135 v8::HandleScope handleScope;
136 // FIXME: should use the plugin's owner frame as the security context
137 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
138 if (context.IsEmpty())
139 return false;
140
141 v8::Context::Scope scope(context);
142
143 // Special case the "eval" method.
144 if (methodName == NPN_GetStringIdentifier("eval")) {
145 if (argCount != 1)
146 return false;
147 if (args[0].type != NPVariantType_String)
148 return false;
149 return NPN_Evaluate(npp, npobj, const_cast<NPString*>(&args[0].value.s tringValue), result);
150 }
151
152 v8::Handle<v8::Value> funcObj = object->v8Object->Get(v8::String::New(id entifier->value.string));
153 if (funcObj.IsEmpty() || funcObj->IsNull()) {
154 NULL_TO_NPVARIANT(*result);
155 return false;
156 }
157 if (funcObj->IsUndefined()) {
158 VOID_TO_NPVARIANT(*result);
159 return false;
160 }
161
162 V8Proxy* proxy = toV8Proxy(npobj);
163 ASSERT(proxy); // must not be null
164
165 // FIXME: fix variable naming
166 // Call the function object
167 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(funcObj);
168 // Create list of args to pass to v8
169 v8::Handle<v8::Value>* argv = listFromVariantArgs(args, argCount, npobj) ;
170 v8::Local<v8::Value> resultObj = proxy->CallFunction(func, object->v8Obj ect, argCount, argv);
171 delete[] argv;
172
173 // If we had an error, return false. The spec is a little unclear here, but
174 // says "Returns true if the method was successfully invoked". If we ge t an
175 // error return value, was that successfully invoked?
176 if (resultObj.IsEmpty())
177 return false;
178
179 // Convert the result back to an NPVariant
180 convertV8ObjectToNPVariant(resultObj, npobj, result);
181 return true;
182 }
183
184 if (npobj->_class->invoke)
185 return npobj->_class->invoke(npobj, methodName, args, argCount, result);
186
187 VOID_TO_NPVARIANT(*result);
188 return true;
189 }
190
191 // FIXME: Fix it same as NPN_Invoke (HandleScope and such)
192 bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
193 uint32_t argCount, NPVariant *result)
194 {
195 if (!npobj)
196 return false;
197
198 if (npobj->_class == npScriptObjectClass) {
199 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
200
201 VOID_TO_NPVARIANT(*result);
202
203 v8::HandleScope handleScope;
204 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
205 if (context.IsEmpty())
206 return false;
207
208 v8::Context::Scope scope(context);
209
210 // Lookup the function object
211 v8::Handle<v8::Object> funcObj(object->v8Object);
212 if (!funcObj->IsFunction())
213 return false;
214
215 // Call the function object
216 v8::Local<v8::Value> resultObj;
217 v8::Handle<v8::Function> func(v8::Function::Cast(*funcObj));
218 if (!func->IsNull()) {
219 V8Proxy* proxy = toV8Proxy(npobj);
220 ASSERT(proxy);
221
222 // Create list of args to pass to v8
223 v8::Handle<v8::Value>* argv = listFromVariantArgs(args, argCount, np obj);
224 resultObj = proxy->CallFunction(func, funcObj, argCount, argv);
225 delete[] argv;
226 }
227
228 // If we had an error, return false. The spec is a little unclear here, but
229 // says "Returns true if the method was successfully invoked". If we ge t an
230 // error return value, was that successfully invoked?
231 if (resultObj.IsEmpty())
232 return false;
233
234 // Convert the result back to an NPVariant.
235 convertV8ObjectToNPVariant(resultObj, npobj, result);
236 return true;
237 }
238
239 if (npobj->_class->invokeDefault)
240 return npobj->_class->invokeDefault(npobj, args, argCount, result);
241
242 VOID_TO_NPVARIANT(*result);
243 return true;
244 }
245
246 bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *npscript, NPVariant *resul t)
247 {
248 bool popupsAllowed = WebCore::ChromiumBridge::popupsAllowed(npp);
249 return NPN_EvaluateHelper(npp, popupsAllowed, npobj, npscript, result);
250 }
251
252 bool NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npobj, NPString* npscript, NPVariant *result)
253 {
254 VOID_TO_NPVARIANT(*result);
255 if (!npobj)
256 return false;
257
258 if (npobj->_class != npScriptObjectClass)
259 return false;
260
261 v8::HandleScope handleScope;
262 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
263 if (context.IsEmpty())
264 return false;
265
266 V8Proxy* proxy = toV8Proxy(npobj);
267 ASSERT(proxy);
268
269 v8::Context::Scope scope(context);
270
271 WebCore::String filename;
272 if (!popupsAllowed)
273 filename = "npscript";
274
275 // Convert UTF-8 stream to WebCore::String.
276 WebCore::String script = WebCore::String::fromUTF8(npscript->UTF8Characters, npscript->UTF8Length);
277 v8::Local<v8::Value> v8result = proxy->evaluate(WebCore::ScriptSourceCode(sc ript, WebCore::KURL(filename)), 0);
278
279 // If we had an error, return false.
280 if (v8result.IsEmpty())
281 return false;
282
283 convertV8ObjectToNPVariant(v8result, npobj, result);
284 return true;
285 }
286
287 bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVari ant *result)
288 {
289 if (!npobj)
290 return false;
291
292 if (npobj->_class == npScriptObjectClass) {
293 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
294
295 v8::HandleScope handleScope;
296 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
297 if (context.IsEmpty())
298 return false;
299
300 v8::Context::Scope scope(context);
301
302 v8::Handle<v8::Object> obj(object->v8Object);
303 v8::Local<v8::Value> v8result = obj->Get(NPIdentifierToV8Identifier(prop ertyName));
304
305 convertV8ObjectToNPVariant(v8result, npobj, result);
306 return true;
307 }
308
309 if (npobj->_class->hasProperty && npobj->_class->getProperty) {
310 if (npobj->_class->hasProperty(npobj, propertyName))
311 return npobj->_class->getProperty(npobj, propertyName, result);
312 }
313
314 VOID_TO_NPVARIANT(*result);
315 return false;
316 }
317
318 bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value)
319 {
320 if (!npobj)
321 return false;
322
323 if (npobj->_class == npScriptObjectClass) {
324 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
325
326 v8::HandleScope handleScope;
327 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
328 if (context.IsEmpty())
329 return false;
330
331 v8::Context::Scope scope(context);
332
333 v8::Handle<v8::Object> obj(object->v8Object);
334 obj->Set(NPIdentifierToV8Identifier(propertyName),
335 convertNPVariantToV8Object(value, object->rootObject->frame()-> script()->windowScriptNPObject()));
336 return true;
337 }
338
339 if (npobj->_class->setProperty)
340 return npobj->_class->setProperty(npobj, propertyName, value);
341
342 return false;
343 }
344
345 bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName)
346 {
347 if (!npobj)
348 return false;
349 if (npobj->_class != npScriptObjectClass)
350 return false;
351
352 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
353
354 v8::HandleScope handleScope;
355 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
356 if (context.IsEmpty())
357 return false;
358 v8::Context::Scope scope(context);
359
360 v8::Handle<v8::Object> obj(object->v8Object);
361 // FIXME(mbelshe) - verify that setting to undefined is right.
362 obj->Set(NPIdentifierToV8Identifier(propertyName), v8::Undefined());
363 return true;
364 }
365
366 bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName)
367 {
368 if (!npobj)
369 return false;
370
371 if (npobj->_class == npScriptObjectClass) {
372 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
373
374 v8::HandleScope handleScope;
375 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
376 if (context.IsEmpty())
377 return false;
378 v8::Context::Scope scope(context);
379
380 v8::Handle<v8::Object> obj(object->v8Object);
381 return obj->Has(NPIdentifierToV8Identifier(propertyName));
382 }
383
384 if (npobj->_class->hasProperty)
385 return npobj->_class->hasProperty(npobj, propertyName);
386 return false;
387 }
388
389 bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName)
390 {
391 if (!npobj)
392 return false;
393
394 if (npobj->_class == npScriptObjectClass) {
395 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
396
397 v8::HandleScope handleScope;
398 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
399 if (context.IsEmpty())
400 return false;
401 v8::Context::Scope scope(context);
402
403 v8::Handle<v8::Object> obj(object->v8Object);
404 v8::Handle<v8::Value> prop = obj->Get(NPIdentifierToV8Identifier(methodN ame));
405 return prop->IsFunction();
406 }
407
408 if (npobj->_class->hasMethod)
409 return npobj->_class->hasMethod(npobj, methodName);
410 return false;
411 }
412
413 void NPN_SetException(NPObject *npobj, const NPUTF8 *message)
414 {
415 if (npobj->_class != npScriptObjectClass)
416 return;
417 v8::HandleScope handleScope;
418 v8::Handle<v8::Context> context = toV8Context(0, npobj);
419 if (context.IsEmpty())
420 return;
421
422 v8::Context::Scope scope(context);
423 V8Proxy::ThrowError(V8Proxy::GENERAL_ERROR, message);
424 }
425
426 bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count)
427 {
428 if (!npobj)
429 return false;
430
431 if (npobj->_class == npScriptObjectClass) {
432 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
433
434 v8::HandleScope handleScope;
435 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
436 if (context.IsEmpty())
437 return false;
438 v8::Context::Scope scope(context);
439
440 v8::Handle<v8::Object> obj(object->v8Object);
441
442 // FIXME(fqian): http://b/issue?id=1210340: Use a v8::Object::Keys() met hod
443 // when it exists, instead of evaluating javascript.
444
445 // FIXME(mpcomplete): figure out how to cache this helper function.
446 // Run a helper function that collects the properties on the object into
447 // an array.
448 const char enumeratorCode[] =
449 "(function (obj) {"
450 " var props = [];"
451 " for (var prop in obj) {"
452 " props[props.length] = prop;"
453 " }"
454 " return props;"
455 "});";
456 v8::Handle<v8::String> source = v8::String::New(enumeratorCode);
457 v8::Handle<v8::Script> script = v8::Script::Compile(source, 0);
458 v8::Handle<v8::Value> enumeratorObj = script->Run();
459 v8::Handle<v8::Function> enumerator = v8::Handle<v8::Function>::Cast(enu meratorObj);
460 v8::Handle<v8::Value> argv[] = { obj };
461 v8::Local<v8::Value> propsObj = enumerator->Call(v8::Handle<v8::Object>: :Cast(enumeratorObj), ARRAYSIZE_UNSAFE(argv), argv);
462 if (propsObj.IsEmpty())
463 return false;
464
465 // Convert the results into an array of NPIdentifiers.
466 v8::Handle<v8::Array> props = v8::Handle<v8::Array>::Cast(propsObj);
467 *count = props->Length();
468 *identifier = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier*) * *count));
469 for (uint32_t i = 0; i < *count; ++i) {
470 v8::Local<v8::Value> name = props->Get(v8::Integer::New(i));
471 (*identifier)[i] = getStringIdentifier(v8::Local<v8::String>::Cast(n ame));
472 }
473 return true;
474 }
475
476 if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) && npobj->_class->enumer ate)
477 return npobj->_class->enumerate(npobj, identifier, count);
478
479 return false;
480 }
481
482 bool NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args, uint32_t arg Count, NPVariant* result)
483 {
484 if (!npobj)
485 return false;
486
487 if (npobj->_class == npScriptObjectClass) {
488 V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
489
490 v8::HandleScope handleScope;
491 v8::Handle<v8::Context> context = toV8Context(npp, npobj);
492 if (context.IsEmpty())
493 return false;
494 v8::Context::Scope scope(context);
495
496 // Lookup the constructor function.
497 v8::Handle<v8::Object> ctorObj(object->v8Object);
498 if (!ctorObj->IsFunction())
499 return false;
500
501 // Call the constructor.
502 v8::Local<v8::Value> resultObj;
503 v8::Handle<v8::Function> ctor(v8::Function::Cast(*ctorObj));
504 if (!ctor->IsNull()) {
505 V8Proxy* proxy = toV8Proxy(npobj);
506 ASSERT(proxy);
507
508 // Create list of args to pass to v8.
509 v8::Handle<v8::Value>* argv = listFromVariantArgs(args, argCount, np obj);
510 resultObj = proxy->NewInstance(ctor, argCount, argv);
511 delete[] argv;
512 }
513
514 // If we had an error return false.
515 if (resultObj.IsEmpty())
516 return false;
517
518 // Convert the result back to an NPVariant.
519 convertV8ObjectToNPVariant(resultObj, npobj, result);
520 return true;
521 }
522
523 if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) && npobj->_class->constr uct)
524 return npobj->_class->construct(npobj, args, argCount, result);
525
526 return false;
527 }
OLDNEW
« no previous file with comments | « webkit/port/bindings/v8/NPV8Object.h ('k') | webkit/port/bindings/v8/V8NPUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698