diff --git a/package.xml b/package.xml index 27330e0..c979893 100644 --- a/package.xml +++ b/package.xml @@ -14,15 +14,18 @@ 2009-02-25 - 0.8dev0.8dev + 0.1.10.1.1 alphaalpha PHP License - - Created package.xml - + * Bug correction on NULL values that would make the app segfault + * Several optimisations on types conversion + * Added tell() function on streams + * Created tests for "make test" + @@ -39,7 +42,7 @@ - 5.3.0 + 5.3.0beta1 1.4.0 @@ -48,19 +51,5 @@ spidermonkey - - - alphaalpha - 0.8dev0.8dev - 2009-02-25 - - - Compile in ZTS mode - - JSRuntime removed for easier usage - - Properties works on objects - - Allow to export classes - - Known issues: - * Using var_dump in JS corrupt the JS engine memory - - - + diff --git a/php_spidermonkey.h b/php_spidermonkey.h index 1e74417..3f7d33a 100644 --- a/php_spidermonkey.h +++ b/php_spidermonkey.h @@ -125,6 +125,7 @@ JSBool js_stream_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv JSBool js_stream_getline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); JSBool js_stream_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); JSBool js_stream_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool js_stream_tell(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); /* }}} */ /* Methods used/exported in JS */ diff --git a/spidermonkey.c b/spidermonkey.c index 6d29347..0c21567 100644 --- a/spidermonkey.c +++ b/spidermonkey.c @@ -257,28 +257,23 @@ void jsval_to_zval(zval *return_value, JSContext *ctx, jsval *jval TSRMLS_DC) rval = *jval; - /* if it's a number or double, convert to double */ - if (JSVAL_IS_NUMBER(rval) || JSVAL_IS_DOUBLE(rval)) + if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) { - jsdouble d; - if (JS_ValueToNumber(ctx, rval, &d) == JS_TRUE) - { - RETVAL_DOUBLE(d); - } - else - RETVAL_FALSE; + RETVAL_NULL(); + } + else if (JSVAL_IS_DOUBLE(rval)) + { + RETVAL_DOUBLE(*JSVAL_TO_DOUBLE(rval)); } else if (JSVAL_IS_INT(rval)) { - int d; - d = JSVAL_TO_INT(rval); - RETVAL_LONG(d); + RETVAL_LONG(JSVAL_TO_INT(rval)); } else if (JSVAL_IS_STRING(rval)) { JSString *str; /* first we convert the jsval to a JSString */ - str = JS_ValueToString(ctx, rval); + str = JSVAL_TO_STRING(rval); if (str != NULL) { /* then we retrieve the pointer to the string */ @@ -310,64 +305,56 @@ void jsval_to_zval(zval *return_value, JSContext *ctx, jsval *jval TSRMLS_DC) php_jscontext_object *intern; php_jsobject_ref *jsref; - if (JS_ValueToObject(ctx, rval, &obj) == JS_TRUE) + //if (JS_ValueToObject(ctx, rval, &obj) == JS_TRUE) + obj = JSVAL_TO_OBJECT(rval); + + intern = (php_jscontext_object*)JS_GetContextPrivate(ctx); + + if ((jsref = (php_jsobject_ref*)JS_GetInstancePrivate(ctx, obj, &intern->script_class, NULL)) == NULL || jsref->obj == NULL) { - intern = (php_jscontext_object*)JS_GetContextPrivate(ctx); + /* create stdClass */ + object_init_ex(return_value, ZEND_STANDARD_CLASS_DEF_PTR); + + /* then iterate on each property */ + it = JS_Enumerate(ctx, obj); - if ((jsref = (php_jsobject_ref*)JS_GetInstancePrivate(ctx, obj, &intern->script_class, NULL)) == NULL || jsref->obj == NULL) + for (i = 0; i < it->length; i++) { - /* create stdClass */ - object_init_ex(return_value, ZEND_STANDARD_CLASS_DEF_PTR); + jsval val; + jsid id = it->vector[i]; + if (JS_IdToValue(ctx, id, &val) == JS_TRUE) + { + JSString *str; + jsval item_val; - /* then iterate on each property */ - it = JS_Enumerate(ctx, obj); + str = JS_ValueToString(ctx, val); - for (i = 0; i < it->length; i++) - { - jsval val; - jsid id = it->vector[i]; - if (JS_IdToValue(ctx, id, &val) == JS_TRUE) + if (js_GetProperty(ctx, obj, id, &item_val) == JS_TRUE) { - JSString *str; - jsval item_val; - - str = JS_ValueToString(ctx, val); - - if (js_GetProperty(ctx, obj, id, &item_val) == JS_TRUE) - { - zval *fval; - char *name; - - /* Retrieve property name */ - name = JS_GetStringBytes(str); - - MAKE_STD_ZVAL(fval); - /* Call this function to convert a jsval to a zval */ - jsval_to_zval(fval, ctx, &item_val TSRMLS_CC); - /* Add property to our stdClass */ - zend_update_property(NULL, return_value, name, strlen(name), fval TSRMLS_CC); - /* Destroy pointer to zval */ - zval_ptr_dtor(&fval); - } + zval *fval; + char *name; + + /* Retrieve property name */ + name = JS_GetStringBytes(str); + + MAKE_STD_ZVAL(fval); + /* Call this function to convert a jsval to a zval */ + jsval_to_zval(fval, ctx, &item_val TSRMLS_CC); + /* Add property to our stdClass */ + zend_update_property(NULL, return_value, name, strlen(name), fval TSRMLS_CC); + /* Destroy pointer to zval */ + zval_ptr_dtor(&fval); } } - - JS_DestroyIdArray(ctx, it); - } - else - { - RETVAL_ZVAL(jsref->obj, 1, NULL); } + + JS_DestroyIdArray(ctx, it); } else { - RETVAL_NULL(); + RETVAL_ZVAL(jsref->obj, 1, NULL); } } - else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) - { - RETVAL_NULL(); - } else /* something is wrong */ RETVAL_FALSE; } @@ -390,12 +377,12 @@ void zval_to_jsval(zval *val, JSContext *ctx, jsval *jval TSRMLS_DC) switch(Z_TYPE_P(val)) { + case IS_LONG: + JS_NewNumberValue(ctx, Z_LVAL_P(val), jval); + break; case IS_DOUBLE: JS_NewNumberValue(ctx, Z_DVAL_P(val), jval); break; - case IS_LONG: - *jval = INT_TO_JSVAL(Z_LVAL_P(val)); - break; case IS_STRING: jstr = JS_NewStringCopyN(ctx, Z_STRVAL_P(val), Z_STRLEN_P(val)); *jval = STRING_TO_JSVAL(jstr); @@ -432,6 +419,7 @@ void zval_to_jsval(zval *val, JSContext *ctx, jsval *jval TSRMLS_DC) JS_DefineFunction(ctx, jobj, "getl", js_stream_getline, 1, 0); JS_DefineFunction(ctx, jobj, "seek", js_stream_seek, 1, 0); JS_DefineFunction(ctx, jobj, "write", js_stream_write, 1, 0); + JS_DefineFunction(ctx, jobj, "tell", js_stream_tell, 1, 0); } /* store pointer to HashTable */ diff --git a/spidermonkey_streams.c b/spidermonkey_streams.c index ea306e1..a98af30 100644 --- a/spidermonkey_streams.c +++ b/spidermonkey_streams.c @@ -33,9 +33,8 @@ JSBool js_stream_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv if (jsref != NULL && jsref->obj != NULL && Z_TYPE_P(jsref->obj) == IS_RESOURCE) { JSString *jstr; - jsval jval; - char *buf; - size_t buf_len, nbytes; + char *buf; + size_t buf_len, nbytes; if (argc >= 1) { @@ -51,9 +50,7 @@ JSBool js_stream_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv php_stream_from_zval_no_verify(stream, &jsref->obj); if (stream == NULL) { - jstr = JS_NewStringCopyN(cx, "Failed to read stream", strlen("Failed to read stream")-1); - jval = STRING_TO_JSVAL(jstr); - JS_SetPendingException(cx, jval); + reportError(cx, "Failed to read stream", NULL); return JS_FALSE; } @@ -90,9 +87,8 @@ JSBool js_stream_getline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, if (jsref != NULL && jsref->obj != NULL && Z_TYPE_P(jsref->obj) == IS_RESOURCE) { JSString *jstr; - jsval jval; - char *buf; - size_t buf_len, nbytes; + char *buf; + size_t buf_len, nbytes; if (argc >= 1) { @@ -107,9 +103,7 @@ JSBool js_stream_getline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, php_stream_from_zval_no_verify(stream, &jsref->obj); if (stream == NULL) { - jstr = JS_NewStringCopyN(cx, "Failed to read stream", strlen("Failed to read stream")-1); - jval = STRING_TO_JSVAL(jstr); - JS_SetPendingException(cx, jval); + reportError(cx, "Failed to read stream", NULL); return JS_FALSE; } @@ -144,9 +138,6 @@ JSBool js_stream_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv jsref = (php_jsobject_ref*)JS_GetInstancePrivate(cx, obj, &intern->script_class, NULL); if (jsref != NULL && jsref->obj != NULL && Z_TYPE_P(jsref->obj) == IS_RESOURCE && argc >= 1) { - JSString *jstr; - jsval jval; - char *buf; off_t pos; int whence; @@ -154,9 +145,7 @@ JSBool js_stream_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv php_stream_from_zval_no_verify(stream, &jsref->obj); if (stream == NULL) { - jstr = JS_NewStringCopyN(cx, "Failed to access stream", strlen("Failed to access stream")-1); - jval = STRING_TO_JSVAL(jstr); - JS_SetPendingException(cx, jval); + reportError(cx, "Failed to access stream", NULL); return JS_FALSE; } @@ -192,17 +181,13 @@ JSBool js_stream_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js if (jsref != NULL && jsref->obj != NULL && Z_TYPE_P(jsref->obj) == IS_RESOURCE && argc >= 1) { JSString *jstr; - jsval jval; - char *buf; - size_t buf_len, nbytes; + size_t buf_len, nbytes; /* fetch php_stream */ php_stream_from_zval_no_verify(stream, &jsref->obj); if (stream == NULL) { - jstr = JS_NewStringCopyN(cx, "Failed to write to stream", strlen("Failed to write to stream")-1); - jval = STRING_TO_JSVAL(jstr); - JS_SetPendingException(cx, jval); + reportError(cx, "Failed to write to stream", NULL); return JS_FALSE; } @@ -221,18 +206,48 @@ JSBool js_stream_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js } } else { - jstr = JS_NewStringCopyN(cx, "Failed to convert type to string", strlen("Failed to convert type to string")-1); - jval = STRING_TO_JSVAL(jstr); - JS_SetPendingException(cx, jval); + reportError(cx, "Failed to convert type to string", NULL); return JS_FALSE; } - *rval = INT_TO_JSVAL(nbytes); + JS_NewNumberValue(cx, nbytes, rval); } return JS_TRUE; } +/* this native is used for telling the position in the file */ +JSBool js_stream_tell(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + TSRMLS_FETCH(); + php_jscontext_object *intern; + php_jsobject_ref *jsref; + php_stream *stream = NULL; + + intern = (php_jscontext_object*)JS_GetContextPrivate(cx); + jsref = (php_jsobject_ref*)JS_GetInstancePrivate(cx, obj, &intern->script_class, NULL); + + if (jsref != NULL && jsref->obj != NULL && Z_TYPE_P(jsref->obj) == IS_RESOURCE) { + off_t file_pos; + + /* fetch php_stream */ + php_stream_from_zval_no_verify(stream, &jsref->obj); + + if (stream == NULL) { + reportError(cx, "Failed to fetch stream", NULL); + return JS_FALSE; + } + + file_pos = php_stream_tell(stream); + + // read from string + JS_NewNumberValue(cx, file_pos, rval); + } + + return JS_TRUE; +} + + /* * Local Variables: * c-basic-offset: 4 diff --git a/test.sh b/test.sh deleted file mode 100755 index eadb370..0000000 --- a/test.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -PHP="php" - -if [ x"$1" != x ]; then - PHP="$1"; -fi; - -echo "**** Running basic tests ****" -echo "$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/base.php" -$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/base.php -echo -echo "**** Running version system tests ****" -echo "$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/version.php" -$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/version.php -echo -echo "**** Running callback system tests ****" -echo "$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/callback.php" -$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/callback.php -#echo -#echo "**** Running reference system tests ****" -#echo "$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/reference.php" -#$PHP -n -d extension_dir=modules/ -d extension=spidermonkey.so mod_tests/reference.php diff --git a/tests/js_streams.phpt b/tests/js_streams.phpt index e1c38bc..2e93ffd 100644 --- a/tests/js_streams.phpt +++ b/tests/js_streams.phpt @@ -17,6 +17,7 @@ fd.seek(1024, fd.SEEK_SET) fd.write('** FOO **') fd.seek(-6, fd.SEEK_CUR) foo = fd.read(3) +print(fd.tell()) fclose(fd) print(foo) @@ -31,6 +32,7 @@ SCR; $js->evaluateScript($script); ?> --EXPECTF-- +1030 FOO $js = new JSContext(); diff --git a/tests/js_types.phpt b/tests/js_types.phpt index caca521..ff47e2f 100644 --- a/tests/js_types.phpt +++ b/tests/js_types.phpt @@ -22,7 +22,7 @@ object(stdClass)#2 (6) { ["str"]=> string(8) "a string" ["long"]=> - float(1337) + int(1337) ["flt"]=> float(13.37) ["bool"]=> @@ -32,20 +32,20 @@ object(stdClass)#2 (6) { ["numarr"]=> object(stdClass)#3 (8) { ["0"]=> - float(1) + int(1) ["1"]=> - float(2) + int(2) ["2"]=> - float(3) + int(3) ["3"]=> - float(5) + int(5) ["4"]=> - float(7) + int(7) ["5"]=> - float(11) + int(11) ["6"]=> - float(13) + int(13) ["7"]=> - float(17) + int(17) } }