Skip to content

Commit

Permalink
Version 0.1.1, corrected a segfault and made several optimisations
Browse files Browse the repository at this point in the history
git-svn-id: https://ookoo.org/svn/pecl-spidermonkey@47 a25dae62-eead-11dd-be30-d70757e1f724
  • Loading branch information
BombStrike authored and BombStrike committed Feb 27, 2009
1 parent 1a7fef3 commit c810137
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 139 deletions.
27 changes: 8 additions & 19 deletions package.xml
Expand Up @@ -14,15 +14,18 @@
</lead>
<date>2009-02-25</date>
<version>
<release>0.8dev</release><api>0.8dev</api>
<release>0.1.1</release><api>0.1.1</api>
</version>
<stability>
<release>alpha</release><api>alpha</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Created package.xml
</notes>
* 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"
</notes>
<contents>
<dir name="/">
<file name="LICENSE" role="doc"/>
Expand All @@ -39,7 +42,7 @@
<dependencies>
<required>
<php>
<min>5.3.0</min>
<min>5.3.0beta1</min>
</php>
<pearinstaller>
<min>1.4.0</min>
Expand All @@ -48,19 +51,5 @@
</dependencies>
<providesextension>spidermonkey</providesextension>
<extsrcrelease/>
<changelog>
<release>
<stability><release>alpha</release><api>alpha</api></stability>
<version><release>0.8dev</release><api>0.8dev</api></version>
<date>2009-02-25</date>
<notes>
- 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
</notes>
</release>
</changelog>
<changelog/>
</package>
1 change: 1 addition & 0 deletions php_spidermonkey.h
Expand Up @@ -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 */
Expand Down
108 changes: 48 additions & 60 deletions spidermonkey.c
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
71 changes: 43 additions & 28 deletions spidermonkey_streams.c
Expand Up @@ -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)
{
Expand All @@ -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;
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}

Expand Down Expand Up @@ -144,19 +138,14 @@ 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;

/* fetch php_stream */
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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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
Expand Down
23 changes: 0 additions & 23 deletions test.sh

This file was deleted.

0 comments on commit c810137

Please sign in to comment.