Index: src/trusted/plugin/var_utils.cc |
diff --git a/src/trusted/plugin/var_utils.cc b/src/trusted/plugin/var_utils.cc |
deleted file mode 100644 |
index 027affc4781db46bcb78b3ecf8a9c0265306b996..0000000000000000000000000000000000000000 |
--- a/src/trusted/plugin/var_utils.cc |
+++ /dev/null |
@@ -1,417 +0,0 @@ |
-// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <assert.h> |
- |
-#include "native_client/src/trusted/plugin/var_utils.h" |
- |
-#include "native_client/src/include/nacl_macros.h" |
-#include "native_client/src/include/nacl_string.h" |
-#include "native_client/src/include/portability_io.h" |
-#include "native_client/src/shared/platform/nacl_check.h" |
-#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
-#include "native_client/src/trusted/plugin/array_ppapi.h" |
-#include "native_client/src/trusted/plugin/desc_based_handle.h" |
-#include "native_client/src/trusted/plugin/scriptable_handle.h" |
-#include "native_client/src/trusted/plugin/utility.h" |
- |
-#include "ppapi/cpp/dev/scriptable_object_deprecated.h" |
- |
-namespace plugin { |
- |
- |
-// In JavaScript, foo[1] is equivalent to foo["1"], so map both indexed and |
-// string names to a string. |
-nacl::string NameAsString(const pp::Var& name) { |
- if (name.is_string()) |
- return name.AsString(); |
- assert(name.is_int()); |
- nacl::stringstream namestream; |
- namestream << name.AsInt(); |
- return namestream.str(); |
-} |
- |
- |
-//----------------------------------------------------------------------------- |
-// Translation from pp::Var to NaClSrpcArg |
-//----------------------------------------------------------------------------- |
- |
-namespace { |
- |
-// Sets |array_length| and allocate |array_data| based on the length |
-// represented by |var|. Sets |exception| on error. |
-template<typename T> void PPVarToAllocateArray(const pp::Var& var, |
- nacl_abi_size_t* array_length, |
- T** array_data, |
- pp::Var* exception) { |
- // Initialize result values for error cases. |
- *array_length = 0; |
- *array_data = NULL; |
- |
- if (!var.is_number()) { |
- *exception = "incompatible argument: unable to get array length"; |
- return; |
- } |
- // AsInt will work if var is int or double. |
- size_t length = var.AsInt(); |
- |
- // Check for overflow on size multiplication and IMC array size limit. |
- if ((length > SIZE_T_MAX / sizeof(T)) || |
- (length * sizeof(T) > NACL_ABI_IMC_USER_BYTES_MAX)) { |
- *exception = "incompatible argument: array length is too long"; |
- return; |
- } |
- |
- *array_length = static_cast<nacl_abi_size_t>(length); |
- *array_data = reinterpret_cast<T*>(malloc(sizeof(T) * length)); |
- if (array_data == NULL) { |
- *exception = "incompatible argument: internal error"; |
- } |
-} |
- |
- |
-// Translates |var| into |array_length| and |array_data| for type |type|. |
-// Sets |exception| on error. |
-template<typename T> void PPVarToArray(const pp::Var& var, |
- nacl_abi_size_t* array_length, |
- T** array_data, |
- pp::Var* exception) { |
- if (!var.is_object()) { |
- *exception = "incompatible argument: type is not array"; |
- return; |
- } |
- pp::VarPrivate var_private(var); |
- |
- pp::Var length_var = var_private.GetProperty(pp::Var("length"), exception); |
- PLUGIN_PRINTF((" PPVarToArray (length=%s)\n", |
- length_var.DebugString().c_str())); |
- PPVarToAllocateArray(length_var, array_length, array_data, exception); |
- if (!exception->is_undefined()) { |
- return; |
- } |
- |
- for (size_t i = 0; i < *array_length; ++i) { |
- int32_t index = nacl::assert_cast<int32_t>(i); |
- pp::Var element = var_private.GetProperty(pp::Var(index), exception); |
- PLUGIN_PRINTF((" PPVarToArray (array[%d]=%s)\n", |
- index, element.DebugString().c_str())); |
- if (!exception->is_undefined()) { |
- break; |
- } |
- if (!element.is_number()) { |
- *exception = "incompatible argument: non-numeric element type"; |
- break; |
- } |
- if (element.is_int()) { |
- (*array_data)[i] = static_cast<T>(element.AsInt()); |
- } else if (element.is_double()) { |
- (*array_data)[i] = static_cast<T>(element.AsDouble()); |
- } else { |
- NACL_NOTREACHED(); |
- } |
- } |
- if (!exception->is_undefined()) { |
- free(array_data); |
- *array_length = 0; |
- *array_data = NULL; |
- } |
-} |
- |
- |
-// Returns the address of |var| if var is an object. Sets |exception| on error. |
-// |var| was passed in from SRPC input marshalling. It is guaranteed to be |
-// alive until the SRPC method is dispatched to. |
-pp::Var* PPVarToObjectVar(const pp::Var& var, pp::Var* exception) { |
- if (!var.is_object()) { |
- *exception = "incompatible argument: type is not object"; |
- return NULL; |
- } |
- return const_cast<pp::Var*>(&var); |
-} |
- |
- |
-// Returns NaClDesc* corresponding to |var|. Sets |exception| on error. |
-NaClDesc* PPVarToNaClDesc(const pp::Var& var, pp::Var* exception) { |
- if (!var.is_object()) { |
- *exception = "incompatible argument: type is not object"; |
- return NULL; |
- } |
- pp::VarPrivate var_private(var); |
- pp::deprecated::ScriptableObject* scriptable_object = |
- var_private.AsScriptableObject(); |
- if (scriptable_object == NULL) { |
- *exception = "incompatible argument: type is not scriptable object"; |
- return NULL; |
- } |
- ScriptableHandle* scriptable_handle = |
- static_cast<ScriptableHandle*>(scriptable_object); |
- if (!ScriptableHandle::is_valid(scriptable_handle)) { |
- *exception = "incompatible argument: not a valid scriptable handle"; |
- return NULL; |
- } |
- NaClDesc* nacl_desc = scriptable_handle->desc_handle()->desc(); |
- if (nacl_desc == NULL) { |
- *exception = "incompatible argument: not a handle object"; |
- return NULL; |
- } |
- return nacl_desc; |
-} |
- |
- |
-// Allocates and returns a pointer to string corresponding to |var|. |
-// Sets |exception| on error. |
-char* PPVarToString(const pp::Var& var, pp::Var* exception) { |
- if (!var.is_string()) { |
- *exception = "incompatible argument: type is not string"; |
- return NULL; |
- } |
- |
- nacl::string var_as_string = var.AsString(); |
- size_t size = var_as_string.size() + 1; // + \0 |
- char* string_as_chars = reinterpret_cast<char*>(malloc(size)); |
- if (string_as_chars == NULL) { |
- *exception = "incompatible argument: internal error"; |
- return NULL; |
- } |
- |
- memcpy(string_as_chars, var_as_string.c_str(), size); |
- return string_as_chars; |
-} |
- |
- |
-// Returns a number corresponding to |var|. JavaScript might mix int and |
-// double types, so use them interchangeably. Sets |exception| on error. |
-template<typename T> T PPVarToNumber(const pp::Var& var, pp::Var* exception) { |
- T result = 0; |
- if (!var.is_number()) |
- *exception = "incompatible argument: type is not numeric"; |
- else if (var.is_double()) |
- result = static_cast<T>(var.AsDouble()); |
- else if (var.is_int()) |
- result = static_cast<T>(var.AsInt()); |
- return result; |
-} |
- |
-} // namespace |
- |
- |
-// Allocates |arg| of the array length represented by |var|. No-op for scalars. |
-// Sets |exception| and returns false on error. |
-bool PPVarToAllocateNaClSrpcArg(const pp::Var& var, |
- NaClSrpcArg* arg, pp::Var* exception) { |
- PLUGIN_PRINTF((" PPVarToAllocateNaClSrpcArg (var=%s, arg->tag='%c')\n", |
- var.DebugString().c_str(), arg->tag)); |
- switch (arg->tag) { |
- case NACL_SRPC_ARG_TYPE_BOOL: |
- case NACL_SRPC_ARG_TYPE_DOUBLE: |
- case NACL_SRPC_ARG_TYPE_INT: |
- case NACL_SRPC_ARG_TYPE_LONG: |
- case NACL_SRPC_ARG_TYPE_STRING: |
- case NACL_SRPC_ARG_TYPE_HANDLE: |
- case NACL_SRPC_ARG_TYPE_OBJECT: |
- break; // nothing to do |
- case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: |
- PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.carr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: |
- PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.darr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_INT_ARRAY: |
- PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.iarr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_LONG_ARRAY: |
- PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.larr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: |
- case NACL_SRPC_ARG_TYPE_INVALID: |
- default: |
- *exception = "variant array and invalid type arguments are not supported"; |
- } |
- PLUGIN_PRINTF((" PPVarToAllocateNaClSrpcArg (return exception=%s)\n", |
- exception->DebugString().c_str())); |
- return exception->is_undefined(); |
-} |
- |
- |
-// Translates |var| into |arg|. Returns false and sets exception on error. |
-bool PPVarToNaClSrpcArg(const pp::Var& var, |
- NaClSrpcArg* arg, pp::Var* exception) { |
- PLUGIN_PRINTF((" PPVarToNaClSrpcArg (var=%s, arg->tag='%c')\n", |
- var.DebugString().c_str(), arg->tag)); |
- switch (arg->tag) { |
- case NACL_SRPC_ARG_TYPE_BOOL: |
- if (!var.is_bool()) |
- *exception = "incompatible argument: type is not bool"; |
- else |
- arg->u.bval = var.AsBool(); |
- break; |
- case NACL_SRPC_ARG_TYPE_DOUBLE: |
- arg->u.dval = PPVarToNumber<double>(var, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_INT: |
- arg->u.ival = PPVarToNumber<int32_t>(var, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_LONG: |
- arg->u.lval = PPVarToNumber<int64_t>(var, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_STRING: |
- arg->arrays.str = PPVarToString(var, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: |
- PPVarToArray(var, &arg->u.count, &arg->arrays.carr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: |
- PPVarToArray(var, &arg->u.count, &arg->arrays.darr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_INT_ARRAY: |
- PPVarToArray(var, &arg->u.count, &arg->arrays.iarr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_LONG_ARRAY: |
- PPVarToArray(var, &arg->u.count, &arg->arrays.larr, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_HANDLE: |
- arg->u.hval = reinterpret_cast<NaClSrpcImcDescType>( |
- PPVarToNaClDesc(var, exception)); |
- break; |
- case NACL_SRPC_ARG_TYPE_OBJECT: |
- arg->arrays.oval = reinterpret_cast<void*>( |
- PPVarToObjectVar(var, exception)); |
- break; |
- case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: |
- case NACL_SRPC_ARG_TYPE_INVALID: |
- default: |
- *exception = "variant array and invalid type arguments are not supported"; |
- } |
- PLUGIN_PRINTF((" PPVarToNaClSrpcArg (return exception=%s)\n", |
- exception->DebugString().c_str())); |
- return exception->is_undefined(); |
-} |
- |
- |
-//----------------------------------------------------------------------------- |
-// Translation NaClSrpcArg to pp::Var |
-//----------------------------------------------------------------------------- |
- |
-namespace { |
- |
-// PPAPI does not have a 64-bit integer Var type. |
-// To make the array construction below work, we define a set of overloaded |
-// functions to convert an array element to a pp::Var. |
-template<typename T> pp::Var ArrayElementToPPVar(T array_element) { |
- return pp::Var(array_element); |
-} |
- |
-// One overload is specialized, and it truncates, losing precision of course. |
-pp::Var ArrayElementToPPVar(int64_t array_element) { |
- return pp::Var(static_cast<int32_t>(array_element)); |
-} |
- |
-// Return a pp::Var constructed from |array_data|. Sets |exception| on error. |
-template<typename T> pp::Var ArrayToPPVar(T* array_data, |
- nacl_abi_size_t array_length, |
- Plugin* plugin, |
- pp::Var* exception) { |
- ArrayPpapi* array = new(std::nothrow) ArrayPpapi(plugin); |
- if (array == NULL) { |
- *exception = "incompatible argument: internal error"; |
- return pp::Var(); |
- } |
- |
- for (size_t i = 0; i < array_length; ++i) { |
- int32_t index = static_cast<int32_t>(i); |
- array->SetProperty(pp::Var(index), |
- ArrayElementToPPVar(array_data[i]), |
- exception); |
- } |
- return pp::VarPrivate(plugin, array); |
-} |
- |
- |
-// Returns a pp::Var corresponding to |desc| or void. Sets |exception| on error. |
-pp::Var NaClDescToPPVar(NaClDesc* desc, Plugin* plugin, pp::Var* exception) { |
- nacl::DescWrapper* wrapper = plugin->wrapper_factory()->MakeGeneric(desc); |
- |
- DescBasedHandle* desc_handle = DescBasedHandle::New(wrapper); |
- |
- pp::deprecated::ScriptableObject* object = |
- ScriptableHandle::NewDescHandle(desc_handle); |
- if (object == NULL) { |
- *exception = "incompatible argument: failed to create handle var"; |
- return pp::Var(); |
- } |
- return pp::VarPrivate(plugin, object); |
-} |
- |
- |
-// Returns a pp::Var corresponding to |obj|. Only predeclared plugin methods |
-// can return objects and they only return a ScriptableHandle that is actually |
-// a ScriptableHandle. |
-pp::Var ObjectToPPVar(void* obj) { |
- ScriptableHandle* handle = reinterpret_cast<ScriptableHandle*>(obj); |
- // This confirms that this this is indeed a valid SriptableHandle that was |
- // created by us. In theory, a predeclared method could receive and return |
- // an opaque JavaScript object that is not a ScriptableHandle. But we don't |
- // have methods like this at the time. If one ever creates such a method, |
- // this CHECK will fail and remind the author to update this code to handle |
- // arbitrary objects. |
- CHECK(ScriptableHandle::is_valid(handle)); |
- if (handle->var() != NULL) |
- return *handle->var(); // make a copy |
- |
- return pp::VarPrivate(handle->plugin(), handle); |
-} |
- |
-} // namespace |
- |
-// Returns a pp::Var corresponding to |arg| or void. Sets |exception| on error. |
-pp::Var NaClSrpcArgToPPVar(const NaClSrpcArg* arg, Plugin* plugin, |
- pp::Var* exception) { |
- PLUGIN_PRINTF((" NaClSrpcArgToPPVar (arg->tag='%c')\n", arg->tag)); |
- pp::Var var; |
- switch (arg->tag) { |
- case NACL_SRPC_ARG_TYPE_BOOL: |
- var = pp::Var(arg->u.bval != 0); |
- break; |
- case NACL_SRPC_ARG_TYPE_DOUBLE: |
- var = pp::Var(arg->u.dval); |
- break; |
- case NACL_SRPC_ARG_TYPE_INT: |
- var = pp::Var(arg->u.ival); |
- break; |
- case NACL_SRPC_ARG_TYPE_LONG: |
- // PPAPI does not have a 64-bit integral type. Downcast. |
- var = pp::Var(static_cast<int32_t>(arg->u.lval)); |
- break; |
- case NACL_SRPC_ARG_TYPE_STRING: |
- var = pp::Var(arg->arrays.str); |
- break; |
- case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: |
- var = ArrayToPPVar(arg->arrays.carr, arg->u.count, plugin, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: |
- var = ArrayToPPVar(arg->arrays.darr, arg->u.count, plugin, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_INT_ARRAY: |
- var = ArrayToPPVar(arg->arrays.iarr, arg->u.count, plugin, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_LONG_ARRAY: |
- var = ArrayToPPVar(arg->arrays.larr, arg->u.count, plugin, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_HANDLE: |
- var = NaClDescToPPVar(arg->u.hval, plugin, exception); |
- break; |
- case NACL_SRPC_ARG_TYPE_OBJECT: |
- var = ObjectToPPVar(arg->arrays.oval); |
- break; |
- case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: |
- case NACL_SRPC_ARG_TYPE_INVALID: |
- default: |
- *exception = "variant array and invalid argument types are not supproted"; |
- } |
- PLUGIN_PRINTF((" NaClSrpcArgToPPVar (return var=%s, exception=%s)\n", |
- var.DebugString().c_str(), exception->DebugString().c_str())); |
- return var; |
-} |
- |
-} // namespace plugin |