| Index: ppapi/shared_impl/var_value_conversions.cc | 
| diff --git a/ppapi/shared_impl/var_value_conversions.cc b/ppapi/shared_impl/var_value_conversions.cc | 
| index 605a984b238d5661ebddb0407f99bcefaf610533..52595218b3d77a68e07610eed06c0b13a6fa23c8 100644 | 
| --- a/ppapi/shared_impl/var_value_conversions.cc | 
| +++ b/ppapi/shared_impl/var_value_conversions.cc | 
| @@ -14,6 +14,7 @@ | 
| #include "base/values.h" | 
| #include "ppapi/c/pp_bool.h" | 
| #include "ppapi/c/pp_stdint.h" | 
| +#include "ppapi/shared_impl/array_var.h" | 
| #include "ppapi/shared_impl/dictionary_var.h" | 
| #include "ppapi/shared_impl/ppapi_globals.h" | 
| #include "ppapi/shared_impl/scoped_pp_var.h" | 
| @@ -39,6 +40,28 @@ class VarNodeBase : public base::RefCounted<VarNodeBase> { | 
| virtual ~VarNodeBase() {} | 
| }; | 
|  | 
| +class ArrayVarNode : public VarNodeBase { | 
| + public: | 
| +  ArrayVarNode(int64_t in_var_id, const ArrayVar* array_var) | 
| +      : var_id(in_var_id), | 
| +        next(array_var->elements().begin()), | 
| +        end(array_var->elements().end()), | 
| +        list_value(new base::ListValue()) { | 
| +  } | 
| + | 
| +  virtual bool IsArrayVar() const OVERRIDE { | 
| +    return true; | 
| +  } | 
| + | 
| +  int64_t var_id; | 
| +  ArrayVar::ElementVector::const_iterator next; | 
| +  ArrayVar::ElementVector::const_iterator end; | 
| +  scoped_ptr<base::ListValue> list_value; | 
| + | 
| + private: | 
| +  virtual ~ArrayVarNode() {} | 
| +}; | 
| + | 
| class DictionaryVarNode : public VarNodeBase { | 
| public: | 
| DictionaryVarNode(int64_t in_var_id, const DictionaryVar* dict_var) | 
| @@ -77,6 +100,27 @@ class ValueNodeBase : public base::RefCounted<ValueNodeBase> { | 
| virtual ~ValueNodeBase() {} | 
| }; | 
|  | 
| +class ListValueNode : public ValueNodeBase { | 
| + public: | 
| +  explicit ListValueNode(const base::ListValue& list_value) | 
| +      : next(list_value.begin()), | 
| +        end(list_value.end()), | 
| +        array_var(new ArrayVar()) { | 
| +    array_var->elements().reserve(list_value.GetSize()); | 
| +  } | 
| + | 
| +  virtual bool IsListValue() const OVERRIDE { | 
| +    return true; | 
| +  } | 
| + | 
| +  base::ListValue::const_iterator next; | 
| +  base::ListValue::const_iterator end; | 
| +  scoped_refptr<ArrayVar> array_var; | 
| + | 
| + private: | 
| +  virtual ~ListValueNode() {} | 
| +}; | 
| + | 
| class DictionaryValueNode : public ValueNodeBase { | 
| public: | 
| explicit DictionaryValueNode(const base::DictionaryValue& dict_value) | 
| @@ -135,8 +179,19 @@ bool CreateValueFromVarHelper(const PP_Var& var, | 
| return false; | 
| } | 
| case PP_VARTYPE_ARRAY: { | 
| -      // TODO(yzshen): Implement it once array var is supported. | 
| -      return false; | 
| +      if (parent_ids->find(var.value.as_id) != parent_ids->end()) { | 
| +        // A circular reference is found. | 
| +        return false; | 
| +      } | 
| + | 
| +      ArrayVar* array_var = ArrayVar::FromPPVar(var); | 
| +      if (!array_var) | 
| +        return false; | 
| + | 
| + | 
| +      parent_ids->insert(var.value.as_id); | 
| +      state->push(new ArrayVarNode(var.value.as_id, array_var)); | 
| +      return true; | 
| } | 
| case PP_VARTYPE_DICTIONARY: { | 
| if (parent_ids->find(var.value.as_id) != parent_ids->end()) { | 
| @@ -241,8 +296,9 @@ bool CreateVarFromValueHelper( | 
| return true; | 
| } | 
| case base::Value::TYPE_LIST: { | 
| -      // TODO(yzshen): Add support once array var is supported. | 
| -      return false; | 
| +      state->push(new ListValueNode( | 
| +          static_cast<const base::ListValue&>(value))); | 
| +      return true; | 
| } | 
| } | 
| NOTREACHED(); | 
| @@ -287,6 +343,22 @@ base::Value* CreateValueFromVar(const PP_Var& var) { | 
| continue; | 
| } | 
| } | 
| +    } else if (state.top()->IsArrayVar()) { | 
| +      scoped_refptr<ArrayVarNode> top( | 
| +          static_cast<ArrayVarNode*>(state.top().get())); | 
| + | 
| +      if (current_value.get()) | 
| +        top->list_value->Append(current_value.release()); | 
| + | 
| +      if (top->next == top->end) { | 
| +        current_value.reset(top->list_value.release()); | 
| +        parent_ids.erase(top->var_id); | 
| +        state.pop(); | 
| +        continue; | 
| +      } else { | 
| +        current_var = top->next->get(); | 
| +        ++top->next; | 
| +      } | 
| } else { | 
| NOTREACHED(); | 
| return NULL; | 
| @@ -333,6 +405,22 @@ PP_Var CreateVarFromValue(const base::Value& value) { | 
| current_value = &top->iter.value(); | 
| top->iter.Advance(); | 
| } | 
| +    } else if (state.top()->IsListValue()) { | 
| +      scoped_refptr<ListValueNode> top( | 
| +          static_cast<ListValueNode*>(state.top().get())); | 
| + | 
| +      if (current_var.get().type != PP_VARTYPE_UNDEFINED) | 
| +        top->array_var->elements().push_back(current_var); | 
| +      current_var = PP_MakeUndefined(); | 
| +      if (top->next == top->end) { | 
| +        current_var = ScopedPPVar(ScopedPPVar::PassRef(), | 
| +                                  top->array_var->GetPPVar()); | 
| +        state.pop(); | 
| +        continue; | 
| +      } else { | 
| +        current_value = *top->next; | 
| +        ++top->next; | 
| +      } | 
| } else { | 
| NOTREACHED(); | 
| return PP_MakeUndefined(); | 
|  |