From 1efd91b29a2117f4fd5ee868bf06e3316fa49977 Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Tue, 25 Nov 2014 23:43:21 +0100 Subject: [PATCH] Add array access offsetSet support --- tests/array_access_basic2.phpt | 57 ++++++++++++++++++++++++++++++ v8js_array_access.cc | 64 +++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 tests/array_access_basic2.phpt diff --git a/tests/array_access_basic2.phpt b/tests/array_access_basic2.phpt new file mode 100644 index 0000000..925eb2c --- /dev/null +++ b/tests/array_access_basic2.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test V8::executeString() : Check array access setter behaviour +--SKIPIF-- + +--INI-- +v8js.use_array_access = 1 +--FILE-- +data[$offset]); + } + + public function offsetGet($offset) { + return $this->data[$offset]; + } + + public function offsetSet($offset, $value) { + $this->data[$offset] = $value; + } + + public function offsetUnset($offset) { + throw new Exception('Not implemented'); + } + + public function count() { + return count($this->data); + } +} + +$myarr = new MyArray(); +$myarr[0] = 'three'; + +$js = <<myarr = $myarr; +$v8->executeString($js); + +var_dump($myarr[2]); + +?> +===EOF=== +--EXPECT-- +string(5) "three" +string(3) "one" +string(13) "three,two,one" +string(3) "one" +===EOF=== diff --git a/v8js_array_access.cc b/v8js_array_access.cc index 2da0e50..b1223ca 100644 --- a/v8js_array_access.cc +++ b/v8js_array_access.cc @@ -68,6 +68,58 @@ static void php_v8js_array_access_getter(uint32_t index, const v8::PropertyCallb } /* }}} */ +static void php_v8js_array_access_setter(uint32_t index, v8::Local value, + const v8::PropertyCallbackInfo& info) /* {{{ */ +{ + v8::Isolate *isolate = info.GetIsolate(); + v8::Local self = info.Holder(); + + zval *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(0)); + zend_class_entry *ce = Z_OBJCE_P(object); + + /* Okay, let's call offsetSet. */ + zend_fcall_info fci; + zval *php_value; + + zval fmember; + INIT_ZVAL(fmember); + ZVAL_STRING(&fmember, "offsetSet", 0); + + zval zindex; + INIT_ZVAL(zindex); + ZVAL_LONG(&zindex, index); + + zval *zvalue_ptr; + MAKE_STD_ZVAL(zvalue_ptr); + if (v8js_to_zval(value, zvalue_ptr, 0, isolate TSRMLS_CC) != SUCCESS) { + info.GetReturnValue().Set(v8::Handle()); + return; + } + + fci.size = sizeof(fci); + fci.function_table = &ce->function_table; + fci.function_name = &fmember; + fci.symbol_table = NULL; + fci.retval_ptr_ptr = &php_value; + + zval *zindex_ptr = &zindex; + zval **params[2] = { &zindex_ptr, &zvalue_ptr }; + + fci.param_count = 2; + fci.params = params; + + fci.object_ptr = object; + fci.no_separation = 0; + + zend_call_function(&fci, NULL TSRMLS_CC); + zval_ptr_dtor(&php_value); + + /* simply pass back the value to tell we intercepted the call + * as the offsetSet function returns void. */ + info.GetReturnValue().Set(value); +} +/* }}} */ + static void php_v8js_array_access_length(v8::Local property, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); @@ -108,7 +160,8 @@ static void php_v8js_array_access_length(v8::Local property, const v v8::Handle php_v8js_array_access_to_jsobj(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */ { v8::Local inst_tpl = v8::ObjectTemplate::New(isolate); - inst_tpl->SetIndexedPropertyHandler(php_v8js_array_access_getter); + inst_tpl->SetIndexedPropertyHandler(php_v8js_array_access_getter, + php_v8js_array_access_setter); inst_tpl->SetAccessor(V8JS_STR("length"), php_v8js_array_access_length); inst_tpl->SetInternalFieldCount(1); @@ -123,3 +176,12 @@ v8::Handle php_v8js_array_access_to_jsobj(zval *value, v8::Isolate *i } /* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */