@@ -640,10 +640,14 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
640
640
objid_t obj, v8::Local<v8::String> method,
641
641
const Nan::FunctionCallbackInfo<v8::Value> &info)
642
642
: 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 ) {
644
645
obj_.SetJsObject (obj);
645
646
}
646
647
~PhpInvokeMsg () override { delete[] argv_; }
648
+ inline bool should_convert_array_to_iterator () {
649
+ return should_convert_array_to_iterator_;
650
+ }
647
651
648
652
protected:
649
653
bool IsEmptyRetvalOk () override {
@@ -756,6 +760,8 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
756
760
return ;
757
761
}
758
762
if (0 == strcmp (cname, " keys" )) {
763
+ // Map#keys() should actually return an Iterator, not an array.
764
+ should_convert_array_to_iterator_ = true ;
759
765
return PhpObject::ArrayEnum (m, EnumOp::ALL, arr,
760
766
&retval_, &exception_ TSRMLS_CC);
761
767
}
@@ -784,6 +790,7 @@ class PhpObject::PhpInvokeMsg : public MessageToPhp {
784
790
Value method_;
785
791
int argc_;
786
792
Value *argv_;
793
+ bool should_convert_array_to_iterator_;
787
794
};
788
795
789
796
@@ -808,6 +815,15 @@ void PhpObject::MethodThunk_(v8::Local<v8::String> method,
808
815
THROW_IF_EXCEPTION (" PHP exception thrown during method invocation" , /* */ );
809
816
if (msg.retval ().IsEmpty ()) {
810
817
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 ()); }
811
827
} else {
812
828
info.GetReturnValue ().Set (msg.retval ().ToJs (channel_));
813
829
}
0 commit comments