void VJSObject::GetPropertyNames( std::vector<VString>& outNames) const
{
	JSPropertyNameArrayRef array = JSObjectCopyPropertyNames( fContext, fObject);
	if (array != NULL)
	{
		size_t size = JSPropertyNameArrayGetCount( array);
		try
		{
			outNames.resize( size);
			size = 0;
			for( std::vector<VString>::iterator i = outNames.begin() ; i != outNames.end() ; ++i)
			{
				JS4D::StringToVString( JSPropertyNameArrayGetNameAtIndex( array, size++), *i);
			}
		}
		catch(...)
		{
			outNames.clear();
		}
		JSPropertyNameArrayRelease( array);
	}
	else
	{
		outNames.clear();
	}
}
Beispiel #2
0
std::unordered_map<std::string, std::string> Object::toJSONMap() const {
  std::unordered_map<std::string, std::string> map;
  auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj);
  size_t count = JSPropertyNameArrayGetCount(namesRef);
  for (size_t i = 0; i < count; i++) {
    auto key = String::ref(JSPropertyNameArrayGetNameAtIndex(namesRef, i));
    map.emplace(key.str(), getProperty(key).toJSONString());
  }
  JSPropertyNameArrayRelease(namesRef);
  return map;
}
Beispiel #3
0
std::vector<std::string> Object::getPropertyNames() const {
  std::vector<std::string> names;
  auto namesRef = JSObjectCopyPropertyNames(m_context, m_obj);
  size_t count = JSPropertyNameArrayGetCount(namesRef);
  for (size_t i = 0; i < count; i++) {
    auto string = String::ref(JSPropertyNameArrayGetNameAtIndex(namesRef, i));
    names.emplace_back(string.str());
  }
  JSPropertyNameArrayRelease(namesRef);
  return names;
}
Beispiel #4
0
bool ObjectWrapper::GetKeys(KeyList& keys)
{
    JSPropertyNameArrayRef names = JSObjectCopyPropertyNames(g_ctx, m_obj);
    size_t len = JSPropertyNameArrayGetCount(names);

    for (size_t i = 0; i < len; ++i)
    {
        JSStringRef name = JSPropertyNameArrayGetNameAtIndex(names, i);
        keys.push_back(JSStringToString(name));
    }

    JSPropertyNameArrayRelease(names);

    return true;
}
Beispiel #5
0
static void
js_obj (JSContextRef ctx, JSObjectRef object, JsonObject * obj)
{
  JSPropertyNameArrayRef props;
  gsize nprops, i;

  props = JSObjectCopyPropertyNames (ctx, object);
  nprops = JSPropertyNameArrayGetCount (props);

  for (i = 0; i < nprops; i++)
    {
      JSStringRef prop = JSPropertyNameArrayGetNameAtIndex (props, i);

      JSValueRef value;
      JsonNode *node;
      gchar *p;

      p = js_string (prop);
g_message("Getting obj property %s\n",p);

      value = JSObjectGetProperty (ctx, object, prop, NULL);
      js_value (ctx, value, &node);

g_message("Got obj property %s\n",p);

debug_print_json_node ( "js_obj(): ", node );

g_message("obj=%p\n",obj);

      json_object_set_member (obj, p, node);

      g_free (p);
      JSStringRelease (prop);
    }
g_message("Done get properties\n");

  JSPropertyNameArrayRelease (props);
}
Beispiel #6
0
GVariant* js_to_dbus(JSContextRef ctx, const JSValueRef jsvalue, const GVariantType* sig, JSValueRef *exception)
{
    if (g_variant_type_is_array(sig)) {
        GVariantBuilder builder;
        g_variant_builder_init(&builder, sig);
        JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue);

        const GVariantType* child_sig = g_variant_type_element(sig);

        if (g_variant_type_is_dict_entry(child_sig)) {

            const GVariantType* key_sig = g_variant_type_first(child_sig);
            const GVariantType* value_sig = g_variant_type_next(key_sig);
            for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
                if (filter_function_child(ctx, jsvalue, i)) continue;

                g_variant_builder_open(&builder, child_sig);
                JSValueRef key = JSValueMakeString(ctx, JSPropertyNameArrayGetNameAtIndex(array, i));
                JSValueRef value = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL);
                g_variant_builder_add_value(&builder, js_to_dbus(ctx, key, key_sig, exception));
                g_variant_builder_add_value(&builder, js_to_dbus(ctx, value, value_sig, exception));
                g_variant_builder_close(&builder);
            }
            return g_variant_builder_end(&builder);

	} else {
	    GVariantBuilder builder;
	    g_variant_builder_init(&builder, sig);
	    JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue);
	    const GVariantType* child_sig = g_variant_type_element(sig);
	    for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
		if (filter_array_child(ctx, array, i)) continue;
		g_variant_builder_add_value(&builder, js_to_dbus(ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL), child_sig, exception));
	    }
	    JSPropertyNameArrayRelease(array);
	    return g_variant_builder_end(&builder);
	}
    } else if (g_variant_type_is_tuple(sig)) {
	    GVariantBuilder builder;
	    g_variant_builder_init(&builder, sig);
	    JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue);
	    const GVariantType* current_sig = g_variant_type_first(sig);
            for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
                if (filter_array_child(ctx, array, i)) continue;
                g_variant_builder_add_value(&builder, js_to_dbus(ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL), current_sig, exception));
		current_sig = g_variant_type_next(current_sig);
            }
            JSPropertyNameArrayRelease(array);
            return g_variant_builder_end(&builder);
    } else {
        switch (g_variant_type_peek_string(sig)[0]) {
            case 'y':
                return g_variant_new_byte(JSValueToNumber(ctx, jsvalue, exception));
            case 'n':
                return g_variant_new_int16(JSValueToNumber(ctx, jsvalue, exception));
            case 'q':
                return g_variant_new_uint16(JSValueToNumber(ctx, jsvalue, exception));
            case 'i':
                return g_variant_new_int32(JSValueToNumber(ctx, jsvalue, exception));
            case 'u':
                return g_variant_new_uint32(JSValueToNumber(ctx, jsvalue, exception));
            case 'x':
                return g_variant_new_int64(JSValueToNumber(ctx, jsvalue, exception));
            case 't':
                return g_variant_new_uint64(JSValueToNumber(ctx, jsvalue, exception));
            case 'd':
                return g_variant_new_double(JSValueToNumber(ctx, jsvalue, exception));
            case 'h':
                return g_variant_new_handle(JSValueToNumber(ctx, jsvalue, exception));
            case 'b':
                return g_variant_new_boolean(JSValueToBoolean(ctx, jsvalue));
            case 's':
                {
                    char* v = jsvalue_to_cstr(ctx, jsvalue);
                    GVariant* r = g_variant_new_string(v);
                    g_free(v);
                    return r;
                }
            case 'v':
                {
                    //TODO:
                    /*g_variant_new_variant()*/
                    g_assert_not_reached();
                }
        }
    }
    g_assert_not_reached();
}
Beispiel #7
0
NATIVE(JSObject,void,releasePropertyNames) (PARAMS, jlong propertyNameArray) {
	JSPropertyNameArrayRelease((JSPropertyNameArrayRef)propertyNameArray);
}
VJSPropertyIterator::~VJSPropertyIterator()
{
	if (fNameArray != NULL)
		JSPropertyNameArrayRelease( fNameArray);
}
Beispiel #9
0
bool script_state_save_single(int script_idx,bool checkpoint,char *err_str)
{
	int						n,count,prop_name_len,prop_value_len;
	char					prop_name[256];
	char					*prop_value;
	script_type				*script;
	JSPropertyNameArrayRef	js_names;
	JSStringRef				js_prop_name,js_prop_json;
	JSValueRef				js_prop_value;

	if (script_idx==-1) return(TRUE);

		// send save state event

	scripts_post_event(script_idx,-1,sd_event_state,(checkpoint?sd_event_state_save_checkpoint:sd_event_state_save),0,err_str);

		// get the script

	script=js.script_list.scripts[script_idx];

		// run through the properities

	js_names=JSObjectCopyPropertyNames(script->cx,script->global_obj);
	count=JSPropertyNameArrayGetCount(js_names);

	for (n=0;n!=count;n++) {

			// get the property name and value

		js_prop_name=JSPropertyNameArrayGetNameAtIndex(js_names,n);
		js_prop_value=JSObjectGetProperty(script->cx,script->global_obj,js_prop_name,NULL);

			// skip all properties that are functions

		if (js_prop_value!=NULL) {
			if (JSValueIsObject(script->cx,js_prop_value)) {
				if (JSObjectIsFunction(script->cx,(JSObjectRef)js_prop_value)) continue;
			}
		}

			// skip all API objects or DIM3 defines

		JSStringGetUTF8CString(js_prop_name,prop_name,256);
		prop_name[255]=0x0;

		if (script_is_prop_global_object(prop_name)) continue;
		if (script_is_prop_define(prop_name)) continue;

			// process the property with JSON

		js_prop_json=JSValueCreateJSONString(script->cx,js_prop_value,0,NULL);
		if (js_prop_json==NULL) continue;
		
		prop_value_len=JSStringGetMaximumUTF8CStringSize(js_prop_json);
		prop_value=(char*)malloc(prop_value_len);
		if (prop_value==NULL) {
			strcpy(err_str,"Out of Memory");
			JSStringRelease(js_prop_json);
			return(FALSE);
		}

		prop_value_len=JSStringGetUTF8CString(js_prop_json,prop_value,prop_value_len);
		JSStringRelease(js_prop_json);
		
			// save property, we have to write a length
			// with each of these because they can be of any size

		prop_name_len=strlen(prop_name)+1;

		game_file_add_chunk(&prop_name_len,1,sizeof(int));
		game_file_add_chunk(prop_name,1,prop_name_len);

		game_file_add_chunk(&prop_value_len,1,sizeof(int));
		game_file_add_chunk(prop_value,1,prop_value_len);

			// free the property value JSON string

		free(prop_value);
	}

	JSPropertyNameArrayRelease(js_names);

		// end each block with a 0 prop name length

	prop_name_len=0;
	game_file_add_chunk(&prop_name_len,1,sizeof(int));

	return(TRUE);
}
Beispiel #10
0
int main(int argc, char* argv[])
{
    const char *scriptPath = "testapi.js";
    if (argc > 1) {
        scriptPath = argv[1];
    }
    
    // Test garbage collection with a fresh context
    context = JSGlobalContextCreateInGroup(NULL, NULL);
    TestInitializeFinalize = true;
    testInitializeFinalize();
    JSGlobalContextRelease(context);
    TestInitializeFinalize = false;

    ASSERT(Base_didFinalize);

    JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty;
    globalObjectClassDefinition.initialize = globalObject_initialize;
    globalObjectClassDefinition.staticValues = globalObject_staticValues;
    globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
    globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
    JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
    context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);

    JSGlobalContextRetain(context);
    JSGlobalContextRelease(context);

    JSObjectRef globalObject = JSContextGetGlobalObject(context);
    ASSERT(JSValueIsObject(context, globalObject));
    
    JSValueRef jsUndefined = JSValueMakeUndefined(context);
    JSValueRef jsNull = JSValueMakeNull(context);
    JSValueRef jsTrue = JSValueMakeBoolean(context, true);
    JSValueRef jsFalse = JSValueMakeBoolean(context, false);
    JSValueRef jsZero = JSValueMakeNumber(context, 0);
    JSValueRef jsOne = JSValueMakeNumber(context, 1);
    JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL);
    JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context));

    // FIXME: test funny utf8 characters
    JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
    JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString);
    
    JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1");
    JSValueRef jsOneString = JSValueMakeString(context, jsOneIString);

    UniChar singleUniChar = 65; // Capital A
    CFMutableStringRef cfString = 
        CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
                                                          &singleUniChar,
                                                          1,
                                                          1,
                                                          kCFAllocatorNull);

    JSStringRef jsCFIString = JSStringCreateWithCFString(cfString);
    JSValueRef jsCFString = JSValueMakeString(context, jsCFIString);
    
    CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
    
    JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString);
    JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString);

    CFIndex cfStringLength = CFStringGetLength(cfString);
    UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar));
    CFStringGetCharacters(cfString, 
                          CFRangeMake(0, cfStringLength), 
                          buffer);
    JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength);
    JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters);
    
    JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString));
    free(buffer);
    JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);

    ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
    ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
    ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
    ASSERT(JSValueGetType(context, jsFalse) == kJSTypeBoolean);
    ASSERT(JSValueGetType(context, jsZero) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsOne) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);

    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
    JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
    JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
    JSStringRelease(myObjectIString);
    
    JSValueRef exception;

    // Conversions that throw exceptions
    exception = NULL;
    ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
    ASSERT(exception);
    
    exception = NULL;
    // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
    // causing a build break with -Wshorten-64-to-32 enabled.  The issue is known by the appropriate team.
    // After that's resolved, we can remove these casts
    ASSERT(isnan((float)JSValueToNumber(context, jsObjectNoProto, &exception)));
    ASSERT(exception);

    exception = NULL;
    ASSERT(!JSValueToStringCopy(context, jsObjectNoProto, &exception));
    ASSERT(exception);
    
    ASSERT(JSValueToBoolean(context, myObject));
    
    exception = NULL;
    ASSERT(!JSValueIsEqual(context, jsObjectNoProto, JSValueMakeNumber(context, 1), &exception));
    ASSERT(exception);
    
    exception = NULL;
    JSObjectGetPropertyAtIndex(context, myObject, 0, &exception);
    ASSERT(1 == JSValueToNumber(context, exception, NULL));

    assertEqualsAsBoolean(jsUndefined, false);
    assertEqualsAsBoolean(jsNull, false);
    assertEqualsAsBoolean(jsTrue, true);
    assertEqualsAsBoolean(jsFalse, false);
    assertEqualsAsBoolean(jsZero, false);
    assertEqualsAsBoolean(jsOne, true);
    assertEqualsAsBoolean(jsOneThird, true);
    assertEqualsAsBoolean(jsEmptyString, false);
    assertEqualsAsBoolean(jsOneString, true);
    assertEqualsAsBoolean(jsCFString, true);
    assertEqualsAsBoolean(jsCFStringWithCharacters, true);
    assertEqualsAsBoolean(jsCFEmptyString, false);
    assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
    
    assertEqualsAsNumber(jsUndefined, nan(""));
    assertEqualsAsNumber(jsNull, 0);
    assertEqualsAsNumber(jsTrue, 1);
    assertEqualsAsNumber(jsFalse, 0);
    assertEqualsAsNumber(jsZero, 0);
    assertEqualsAsNumber(jsOne, 1);
    assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
    assertEqualsAsNumber(jsEmptyString, 0);
    assertEqualsAsNumber(jsOneString, 1);
    assertEqualsAsNumber(jsCFString, nan(""));
    assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
    assertEqualsAsNumber(jsCFEmptyString, 0);
    assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
    ASSERT(sizeof(JSChar) == sizeof(UniChar));
    
    assertEqualsAsCharactersPtr(jsUndefined, "undefined");
    assertEqualsAsCharactersPtr(jsNull, "null");
    assertEqualsAsCharactersPtr(jsTrue, "true");
    assertEqualsAsCharactersPtr(jsFalse, "false");
    assertEqualsAsCharactersPtr(jsZero, "0");
    assertEqualsAsCharactersPtr(jsOne, "1");
    assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
    assertEqualsAsCharactersPtr(jsEmptyString, "");
    assertEqualsAsCharactersPtr(jsOneString, "1");
    assertEqualsAsCharactersPtr(jsCFString, "A");
    assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
    assertEqualsAsCharactersPtr(jsCFEmptyString, "");
    assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
    
    assertEqualsAsUTF8String(jsUndefined, "undefined");
    assertEqualsAsUTF8String(jsNull, "null");
    assertEqualsAsUTF8String(jsTrue, "true");
    assertEqualsAsUTF8String(jsFalse, "false");
    assertEqualsAsUTF8String(jsZero, "0");
    assertEqualsAsUTF8String(jsOne, "1");
    assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
    assertEqualsAsUTF8String(jsEmptyString, "");
    assertEqualsAsUTF8String(jsOneString, "1");
    assertEqualsAsUTF8String(jsCFString, "A");
    assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
    assertEqualsAsUTF8String(jsCFEmptyString, "");
    assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
    
    ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue));
    ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString));

    ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL));
    ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL));
    
    CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString);
    CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString);
    ASSERT(CFEqual(cfJSString, cfString));
    ASSERT(CFEqual(cfJSEmptyString, cfEmptyString));
    CFRelease(cfJSString);
    CFRelease(cfJSEmptyString);

    CFRelease(cfString);
    CFRelease(cfEmptyString);
    
    jsGlobalValue = JSObjectMake(context, NULL, NULL);
    JSValueProtect(context, jsGlobalValue);
    JSGarbageCollect(context);
    ASSERT(JSValueIsObject(context, jsGlobalValue));
    JSValueUnprotect(context, jsGlobalValue);

    JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
    JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
    ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
    ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));

    JSValueRef result;
    JSValueRef v;
    JSObjectRef o;
    JSStringRef string;

    result = JSEvaluateScript(context, goodSyntax, NULL, NULL, 1, NULL);
    ASSERT(result);
    ASSERT(JSValueIsEqual(context, result, jsOne, NULL));

    exception = NULL;
    result = JSEvaluateScript(context, badSyntax, NULL, NULL, 1, &exception);
    ASSERT(!result);
    ASSERT(JSValueIsObject(context, exception));
    
    JSStringRef array = JSStringCreateWithUTF8CString("Array");
    JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
    JSStringRelease(array);
    result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL);
    ASSERT(result);
    ASSERT(JSValueIsObject(context, result));
    ASSERT(JSValueIsInstanceOfConstructor(context, result, arrayConstructor, NULL));
    ASSERT(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(context), arrayConstructor, NULL));

    o = JSValueToObject(context, result, NULL);
    exception = NULL;
    ASSERT(JSValueIsUndefined(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception)));
    ASSERT(!exception);
    
    JSObjectSetPropertyAtIndex(context, o, 0, JSValueMakeNumber(context, 1), &exception);
    ASSERT(!exception);
    
    exception = NULL;
    ASSERT(1 == JSValueToNumber(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception), &exception));
    ASSERT(!exception);

    JSStringRef functionBody;
    JSObjectRef function;
    
    exception = NULL;
    functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
    JSStringRef line = JSStringCreateWithUTF8CString("line");
    ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
    ASSERT(JSValueIsObject(context, exception));
    v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
    assertEqualsAsNumber(v, 1);
    JSStringRelease(functionBody);
    JSStringRelease(line);

    exception = NULL;
    functionBody = JSStringCreateWithUTF8CString("return Array;");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception);
    JSStringRelease(functionBody);
    ASSERT(!exception);
    ASSERT(JSObjectIsFunction(context, function));
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(v);
    ASSERT(JSValueIsEqual(context, v, arrayConstructor, NULL));
    
    exception = NULL;
    function = JSObjectMakeFunction(context, NULL, 0, NULL, jsEmptyIString, NULL, 0, &exception);
    ASSERT(!exception);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, &exception);
    ASSERT(v && !exception);
    ASSERT(JSValueIsUndefined(context, v));
    
    exception = NULL;
    v = NULL;
    JSStringRef foo = JSStringCreateWithUTF8CString("foo");
    JSStringRef argumentNames[] = { foo };
    functionBody = JSStringCreateWithUTF8CString("return foo;");
    function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception);
    ASSERT(function && !exception);
    JSValueRef arguments[] = { JSValueMakeNumber(context, 2) };
    v = JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception);
    JSStringRelease(foo);
    JSStringRelease(functionBody);
    
    string = JSValueToStringCopy(context, function, NULL);
    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {return foo;}");
    JSStringRelease(string);

    JSStringRef print = JSStringCreateWithUTF8CString("print");
    JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(context, print, print_callAsFunction);
    JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone, NULL); 
    JSStringRelease(print);
    
    ASSERT(!JSObjectSetPrivate(printFunction, (void*)1));
    ASSERT(!JSObjectGetPrivate(printFunction));

    JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor");
    JSObjectRef myConstructor = JSObjectMakeConstructor(context, NULL, myConstructor_callAsConstructor);
    JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL);
    JSStringRelease(myConstructorIString);
    
    ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1));
    ASSERT(!JSObjectGetPrivate(myConstructor));
    
    string = JSStringCreateWithUTF8CString("Derived");
    JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL);
    JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL);
    JSStringRelease(string);
    
    o = JSObjectMake(context, NULL, NULL);
    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
    JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
    JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
    size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
    size_t count;
    for (count = 0; count < expectedCount; ++count)
        JSPropertyNameArrayGetNameAtIndex(nameArray, count);
    JSPropertyNameArrayRelease(nameArray);
    ASSERT(count == 1); // jsCFString should not be enumerated

    JSClassDefinition nullDefinition = kJSClassDefinitionEmpty;
    nullDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
    JSClassRef nullClass = JSClassCreate(&nullDefinition);
    JSClassRelease(nullClass);
    
    nullDefinition = kJSClassDefinitionEmpty;
    nullClass = JSClassCreate(&nullDefinition);
    JSClassRelease(nullClass);

    functionBody = JSStringCreateWithUTF8CString("return this;");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
    JSStringRelease(functionBody);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));

    functionBody = JSStringCreateWithUTF8CString("return eval(\"this\");");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
    JSStringRelease(functionBody);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));

    JSStringRef script = JSStringCreateWithUTF8CString("this;");
    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));
    JSStringRelease(script);

    script = JSStringCreateWithUTF8CString("eval(this);");
    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));
    JSStringRelease(script);

    char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
    if (!scriptUTF8)
        printf("FAIL: Test script could not be loaded.\n");
    else {
        script = JSStringCreateWithUTF8CString(scriptUTF8);
        result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
        if (JSValueIsUndefined(context, result))
            printf("PASS: Test script executed successfully.\n");
        else {
            printf("FAIL: Test script returned unexpected value:\n");
            JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
            CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString);
            CFShow(exceptionCF);
            CFRelease(exceptionCF);
            JSStringRelease(exceptionIString);
        }
        JSStringRelease(script);
        free(scriptUTF8);
    }

    // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
    function = NULL;
    v = NULL;
    o = NULL;
    globalObject = NULL;

    JSStringRelease(jsEmptyIString);
    JSStringRelease(jsOneIString);
    JSStringRelease(jsCFIString);
    JSStringRelease(jsCFEmptyIString);
    JSStringRelease(jsCFIStringWithCharacters);
    JSStringRelease(jsCFEmptyIStringWithCharacters);
    JSStringRelease(goodSyntax);
    JSStringRelease(badSyntax);

    JSGlobalContextRelease(context);
    JSClassRelease(globalObjectClass);

    printf("PASS: Program exited normally.\n");
    return 0;
}
Beispiel #11
0
gboolean js_to_dbus(JSContextRef ctx, const JSValueRef jsvalue,
    DBusMessageIter *iter, const char* sig, JSValueRef* exception)
{
    DBusSignatureIter s_iter;
    dbus_signature_iter_init(&s_iter, sig);

    int type;
    switch (type = dbus_signature_iter_get_current_type(&s_iter)) {
        case DBUS_TYPE_BOOLEAN:
            {
                dbus_bool_t value = JSValueToBoolean(ctx, jsvalue);
                if (!dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_warning("signatuer:%c error!", type);
                    return FALSE;
                }  else {
                    return TRUE;
                }
            }
        case DBUS_TYPE_DOUBLE:
            CASE_NUMBER
            {
                if (!JSValueIsNumber(ctx, jsvalue)) {
                    js_fill_exception(ctx, exception, "jsvalue is not an number!");
                    return FALSE;
                }
                double value = JSValueToNumber(ctx, jsvalue, NULL);
                if (!dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_warning("signatuer:%c error!", type);
                    return FALSE;
                } else {
                    return TRUE;
                }
            }
            CASE_STRING
            {
                char* value = jsvalue_to_cstr(ctx, jsvalue);
                if (value == NULL ||
                        !dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_free(value);
                    js_fill_exception(ctx, exception, "jsvalue is not an string or memory not enough!");
                    return FALSE;
                } else {
                    g_free(value);
                    return TRUE;
                }
            }

        case DBUS_TYPE_STRUCT:
            {
                if (!jsvalue_instanceof(ctx, jsvalue, "Array")) {
                    js_fill_exception(ctx, exception, "jsvalue should an array");
                    return FALSE;
                }

                JSPropertyNameArrayRef prop_names =
                    JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue);
                int p_num = JSPropertyNameArrayGetCount(prop_names);
                if (p_num == 0) {
                    JSPropertyNameArrayRelease(prop_names);
                    js_fill_exception(ctx, exception, "Struct at least have one element!");
                    return FALSE;
                }

                DBusMessageIter sub_iter;
                OPEN_CONTAINER(iter, type, NULL, &sub_iter);

                DBusSignatureIter sub_s_iter;
                dbus_signature_iter_recurse(&s_iter, &sub_s_iter);

                for (int i=0; i<p_num; i++) {
                    JSValueRef value = JSObjectGetProperty(ctx,
                            (JSObjectRef)jsvalue,
                            JSPropertyNameArrayGetNameAtIndex(prop_names, i),
                            NULL);

                    char *sig = dbus_signature_iter_get_signature(&sub_s_iter);
                    if (!js_to_dbus(ctx, value, &sub_iter, sig, exception)) {
                        js_fill_exception(ctx, exception, "Failed append struct with sig:%sTODO");
                        dbus_free(sig);
                        return FALSE;
                    }
                    dbus_free(sig);

                    if (i != p_num-1 && !dbus_signature_iter_next(&sub_s_iter)) {
                        JSPropertyNameArrayRelease(prop_names);
                        CLOSE_CONTAINER(iter, &sub_iter);
                        js_fill_exception(ctx, exception, "to many params filled to struct");
                        return FALSE;
                    }
                }

                if (dbus_signature_iter_next(&sub_s_iter)) {
                    JSPropertyNameArrayRelease(prop_names);
                    CLOSE_CONTAINER(iter, &sub_iter);
                    js_fill_exception(ctx, exception, "need more params by this struct");
                    return FALSE;
                }
                JSPropertyNameArrayRelease(prop_names);
                CLOSE_CONTAINER(iter, &sub_iter);
                return TRUE;
            }
        case DBUS_TYPE_ARRAY:
            if (dbus_signature_iter_get_element_type(&s_iter) ==
                    DBUS_TYPE_DICT_ENTRY) {

                DBusSignatureIter dict_s_iter;
                dbus_signature_iter_recurse(&s_iter, &dict_s_iter);
                char *d_sig = dbus_signature_iter_get_signature(&dict_s_iter);

                DBusMessageIter sub_iter;
                OPEN_CONTAINER(iter, type, d_sig, &sub_iter);
                dbus_free(d_sig);

                JSPropertyNameArrayRef prop_names = JSObjectCopyPropertyNames(ctx,
                        (JSObjectRef)jsvalue);
                int p_num = JSPropertyNameArrayGetCount(prop_names);

                DBusSignatureIter dict_sub_s_iter;
                dbus_signature_iter_recurse(&dict_s_iter, &dict_sub_s_iter);

                int key_type = dbus_signature_iter_get_current_type(&dict_sub_s_iter);
                dbus_signature_iter_next(&dict_sub_s_iter);
                char *val_sig = dbus_signature_iter_get_signature(&dict_sub_s_iter);


                for (int i=0; i<p_num; i++) {
                    DBusMessageIter dict_iter;
                    OPEN_CONTAINER(&sub_iter, DBUS_TYPE_DICT_ENTRY,
                            NULL, &dict_iter);

                    JSStringRef key_str = JSPropertyNameArrayGetNameAtIndex(prop_names, i);

                    //TODO: fetch key type
                    switch (key_type) {
                        CASE_STRING
                        {
                            char *value = jsstring_to_cstr(ctx, key_str);
                            dbus_message_iter_append_basic(&dict_iter, key_type, (void*)&value);
                            g_free(value);
                            break;
                        }
                        case DBUS_TYPE_DOUBLE:
                        CASE_NUMBER
                        {
                            //TODO detect illegal number format
                            JSValueRef excp;
                            double value = JSValueToNumber(ctx,
                                    JSValueMakeString(ctx, key_str), &excp);

                            if (excp != NULL) {
                                js_fill_exception(ctx, exception, "dict_entry's key must be an number to match the signature!");
                                return FALSE;
                            }

                            dbus_message_iter_append_basic(&dict_iter, key_type,
                                    (void*)&value);
                            break;
                        }
                        default:
                        {
                            js_fill_exception(ctx, exception, "DICT_ENTRY's key must basic type, and you should not see this warning in javascript runtime");
                            dbus_free(val_sig);
                            JSPropertyNameArrayRelease(prop_names);
                            CLOSE_CONTAINER(iter, &sub_iter);
                            return FALSE;
                        }
                    }



                    js_to_dbus(ctx,
                            JSObjectGetProperty(ctx, (JSObjectRef)jsvalue,
                                key_str, NULL),
                            &dict_iter, val_sig,
                            exception);

                    CLOSE_CONTAINER(&sub_iter, &dict_iter);
                }
                dbus_free(val_sig);
                JSPropertyNameArrayRelease(prop_names);

                CLOSE_CONTAINER(iter, &sub_iter);
                return TRUE;
            } else {