| Index: webkit/plugins/ppapi/message_channel.cc
|
| diff --git a/webkit/plugins/ppapi/message_channel.cc b/webkit/plugins/ppapi/message_channel.cc
|
| index 4a9fdd09dc7b14f108200c6d12ef8921c37455aa..857a94592cdd89edf0b2e1ddddd66536246099f0 100644
|
| --- a/webkit/plugins/ppapi/message_channel.cc
|
| +++ b/webkit/plugins/ppapi/message_channel.cc
|
| @@ -26,6 +26,7 @@
|
| #include "webkit/plugins/ppapi/npapi_glue.h"
|
| #include "webkit/plugins/ppapi/plugin_module.h"
|
| #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
|
| +#include "webkit/plugins/ppapi/v8_var_converter.h"
|
|
|
| using ppapi::ArrayBufferVar;
|
| using ppapi::PpapiGlobals;
|
| @@ -62,96 +63,80 @@ bool IdentifierIsPostMessage(NPIdentifier identifier) {
|
| return WebBindings::getStringIdentifier(kPostMessage) == identifier;
|
| }
|
|
|
| -// Converts the given PP_Var to a v8::Value, returning true on success.
|
| -// False means that the given variant is invalid. In this case, |result| will
|
| -// be set to an empty handle.
|
| -bool PPVarToV8Value(PP_Var var, v8::Handle<v8::Value>* result) {
|
| +bool NPVariantToPPVar(const NPVariant* variant, PP_Var* result) {
|
| + switch (variant->type) {
|
| + case NPVariantType_Void:
|
| + *result = PP_MakeUndefined();
|
| + return true;
|
| + case NPVariantType_Null:
|
| + *result = PP_MakeNull();
|
| + return true;
|
| + case NPVariantType_Bool:
|
| + *result = PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)));
|
| + return true;
|
| + case NPVariantType_Int32:
|
| + *result = PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
|
| + return true;
|
| + case NPVariantType_Double:
|
| + *result = PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
|
| + return true;
|
| + case NPVariantType_String:
|
| + *result = StringVar::StringToPPVar(
|
| + NPVARIANT_TO_STRING(*variant).UTF8Characters,
|
| + NPVARIANT_TO_STRING(*variant).UTF8Length);
|
| + return true;
|
| + case NPVariantType_Object:
|
| + V8VarConverter converter;
|
| + // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it
|
| + // shouldn't result in a deep copy.
|
| + return converter.FromV8Value(WebBindings::toV8Value(variant),
|
| + v8::Context::GetCurrent(), result);
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +// Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage.
|
| +// This currently just copies the value. For a string Var, the result is a
|
| +// PP_Var with the a copy of |var|'s string contents and a reference count of 1.
|
| +PP_Var CopyPPVar(const PP_Var& var) {
|
| switch (var.type) {
|
| case PP_VARTYPE_UNDEFINED:
|
| - *result = v8::Undefined();
|
| - break;
|
| case PP_VARTYPE_NULL:
|
| - *result = v8::Null();
|
| - break;
|
| case PP_VARTYPE_BOOL:
|
| - *result = (var.value.as_bool == PP_TRUE) ? v8::True() : v8::False();
|
| - break;
|
| case PP_VARTYPE_INT32:
|
| - *result = v8::Integer::New(var.value.as_int);
|
| - break;
|
| case PP_VARTYPE_DOUBLE:
|
| - *result = v8::Number::New(var.value.as_double);
|
| - break;
|
| + return var;
|
| case PP_VARTYPE_STRING: {
|
| StringVar* string = StringVar::FromPPVar(var);
|
| - if (!string) {
|
| - result->Clear();
|
| - return false;
|
| - }
|
| - const std::string& value = string->value();
|
| - // TODO(dmichael): We should consider caching the V8 string in the host-
|
| - // side StringVar, so that we only have to convert/copy once if a
|
| - // string is sent more than once.
|
| - *result = v8::String::New(value.c_str(), value.size());
|
| - break;
|
| + if (!string)
|
| + return PP_MakeUndefined();
|
| + return StringVar::StringToPPVar(string->value());
|
| }
|
| case PP_VARTYPE_ARRAY_BUFFER: {
|
| ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var);
|
| - if (!buffer) {
|
| - result->Clear();
|
| - return false;
|
| - }
|
| - HostArrayBufferVar* host_buffer =
|
| - static_cast<HostArrayBufferVar*>(buffer);
|
| - *result =
|
| - v8::Local<v8::Value>::New(host_buffer->webkit_buffer().toV8Value());
|
| - break;
|
| + if (!buffer)
|
| + return PP_MakeUndefined();
|
| + PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()->
|
| + MakeArrayBufferPPVar(buffer->ByteLength());
|
| + DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER);
|
| + if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER)
|
| + return PP_MakeUndefined();
|
| + ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var);
|
| + DCHECK(new_buffer);
|
| + if (!new_buffer)
|
| + return PP_MakeUndefined();
|
| + memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength());
|
| + return new_buffer_var;
|
| }
|
| case PP_VARTYPE_OBJECT:
|
| case PP_VARTYPE_ARRAY:
|
| case PP_VARTYPE_DICTIONARY:
|
| - // These are not currently supported.
|
| - NOTIMPLEMENTED();
|
| - result->Clear();
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage.
|
| -// This currently just copies the value. For a string Var, the result is a
|
| -// PP_Var with the a copy of |var|'s string contents and a reference count of 1.
|
| -//
|
| -// TODO(dmichael): Bypass this step for out-of-process plugins, since a copy
|
| -// happens already when the Var is serialized.
|
| -PP_Var CopyPPVar(const PP_Var& var) {
|
| - if (var.type == PP_VARTYPE_OBJECT) {
|
| - // Objects are not currently supported.
|
| - NOTIMPLEMENTED();
|
| - return PP_MakeUndefined();
|
| - } else if (var.type == PP_VARTYPE_STRING) {
|
| - StringVar* string = StringVar::FromPPVar(var);
|
| - if (!string)
|
| - return PP_MakeUndefined();
|
| - return StringVar::StringToPPVar(string->value());
|
| - } else if (var.type == PP_VARTYPE_ARRAY_BUFFER) {
|
| - ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var);
|
| - if (!buffer)
|
| - return PP_MakeUndefined();
|
| - PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()->
|
| - MakeArrayBufferPPVar(buffer->ByteLength());
|
| - DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER);
|
| - if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER)
|
| - return PP_MakeUndefined();
|
| - ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var);
|
| - DCHECK(new_buffer);
|
| - if (!new_buffer)
|
| + // Objects/Arrays/Dictionaries not supported by PostMessage in-process.
|
| + NOTREACHED();
|
| return PP_MakeUndefined();
|
| - memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength());
|
| - return new_buffer_var;
|
| - } else {
|
| - return var;
|
| }
|
| + NOTREACHED();
|
| + return PP_MakeUndefined();
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| @@ -195,7 +180,11 @@ bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name,
|
| if (IdentifierIsPostMessage(name) && (arg_count == 1)) {
|
| MessageChannel* message_channel = ToMessageChannel(np_obj);
|
| if (message_channel) {
|
| - PP_Var argument(NPVariantToPPVar(message_channel->instance(), &args[0]));
|
| + PP_Var argument = PP_MakeUndefined();
|
| + if (!NPVariantToPPVar(&args[0], &argument)) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| message_channel->PostMessageToNative(argument);
|
| PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument);
|
| return true;
|
| @@ -357,11 +346,23 @@ void MessageChannel::PostMessageToJavaScript(PP_Var message_data) {
|
| v8::Context::Scope context_scope(context);
|
|
|
| v8::Local<v8::Value> v8_val;
|
| - if (!PPVarToV8Value(message_data, &v8_val)) {
|
| + V8VarConverter converter;
|
| + if (!converter.ToV8Value(message_data, context, &v8_val)) {
|
| NOTREACHED();
|
| return;
|
| }
|
|
|
| + // This is for backward compatibility. It usually makes sense for us to return
|
| + // a string object rather than a string primitive because it allows multiple
|
| + // references to the same string (as with PP_Var strings). However, prior to
|
| + // implementing dictionary and array, vars we would return a string primitive
|
| + // here. Changing it to an object now will break existing code that uses
|
| + // strict comparisons for strings returned from PostMessage. e.g. x === "123"
|
| + // will no longer return true. So if the only value to return is a string
|
| + // object, just return the string primitive.
|
| + if (v8_val->IsStringObject())
|
| + v8_val = v8_val->ToString();
|
| +
|
| WebSerializedScriptValue serialized_val =
|
| WebSerializedScriptValue::serialize(v8_val);
|
|
|
|
|