@@ -640,10 +640,14 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
640640 objid_t obj, v8::Local<v8::String> method,
641641 const Nan::FunctionCallbackInfo<v8::Value> &info)
642642 : MessageToPhp(m, callback, is_sync), method_(m, method),
643- argc_ (info.Length()), argv_(Value::NewArray(m, info)) {
643+ argc_ (info.Length()), argv_(Value::NewArray(m, info)),
644+ should_convert_array_to_iterator_(false ) {
644645 obj_.SetJsObject (obj);
645646 }
646647 ~PhpInvokeMsg () override { delete[] argv_; }
648+ inline bool should_convert_array_to_iterator () {
649+ return should_convert_array_to_iterator_;
650+ }
647651
648652 protected:
649653 bool IsEmptyRetvalOk () override {
@@ -756,6 +760,8 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
756760 return ;
757761 }
758762 if (0 == strcmp (cname, " keys" )) {
763+ // Map#keys() should actually return an Iterator, not an array.
764+ should_convert_array_to_iterator_ = true ;
759765 return PhpObject::ArrayEnum (m, EnumOp::ALL, arr,
760766 &retval_, &exception_ TSRMLS_CC);
761767 }
@@ -784,6 +790,7 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
784790 Value method_;
785791 int argc_;
786792 Value *argv_;
793+ bool should_convert_array_to_iterator_;
787794};
788795
789796
@@ -808,6 +815,15 @@ void PhpObject::MethodThunk_(v8::Local<v8::String> method,
808815 THROW_IF_EXCEPTION (" PHP exception thrown during method invocation" , /* */ );
809816 if (msg.retval ().IsEmpty ()) {
810817 info.GetReturnValue ().Set (Nan::Undefined ());
818+ } else if (msg.should_convert_array_to_iterator ()) {
819+ // Map#keys() method should actually return an iterator, not an
820+ // array, so call Array#values() on the result.
821+ v8::Local<v8::Array> r = msg.retval ().ToJs (channel_).As <v8::Array>();
822+ v8::Local<v8::Object> values = Nan::Get (r, NEW_STR (" values" ))
823+ .ToLocalChecked ().As <v8::Object>();
824+ Nan::MaybeLocal<v8::Value> newr =
825+ Nan::CallAsFunction (values, r, 0 , nullptr );
826+ if (!newr.IsEmpty ()) { info.GetReturnValue ().Set (newr.ToLocalChecked ()); }
811827 } else {
812828 info.GetReturnValue ().Set (msg.retval ().ToJs (channel_));
813829 }
0 commit comments