Wednesday, August 27, 2014

Calling a Rust library from C (or anything else!)

One reason I'm excited about Rust is that I can compile Rust code to a simple native-code library, without heavy runtime dependencies, and then call it from any language. Imagine writing performance-critical extensions for Python, Ruby, or Node in a safe, pleasant language that has static lifetime checking, pattern matching, a real macro system, and other goodies like that. For this reason, when I started html5ever some six months ago, I wanted it to be more than another "Foo for BarLang" project. I want it to be the HTML parser of choice, for a wide variety of applications in any language.

Today I started work in earnest on the C API for html5ever. In only a few hours I had a working demo. And this is a fairly complicated library, with 5,000+ lines of code incorporating

It's pretty cool that we can use all this machinery from C, or any language that can call C. I'll describe first how to build and use the library, and then I'll talk about the implementation of the C API.

html5ever (for C or for Rust) is not finished yet, but if you're feeling adventurous, you are welcome to try it out! And I'd love to have more contributors. Let me know on GitHub about any issues you run into.

Using html5ever from C

Like most Rust libraries, html5ever builds with Cargo.

$ git clone https://github.com/kmcallister/html5ever
$ cd html5ever
$ git checkout dev
$ cargo build
    Updating git repository `https://github.com/sfackler/rust-phf`
   Compiling phf_mac v0.0.0 (https://github.com/sfackler/rust-phf#f21e2a41)
   Compiling html5ever-macros v0.0.0 (file:///tmp/html5ever)
   Compiling phf v0.0.0 (https://github.com/sfackler/rust-phf#f21e2a41)
   Compiling html5ever v0.0.0 (file:///tmp/html5ever)

The C API isn't Cargo-ified yet, so we'll build it using the older Makefile-based system.

$ mkdir build
$ cd build
$ ../configure
$ make libhtml5ever_for_c.a
rustc -D warnings -C rpath -L /tmp/html5ever/target -L /tmp/html5ever/target/deps \
  -o libhtml5ever_for_c.a --cfg for_c --crate-type staticlib /tmp/html5ever/src/lib.rs
warning: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: rt
note: library: dl
note: library: pthread
note: library: gcc_s
note: library: pthread
note: library: c
note: library: m

Now we can build an example C program using that library, and following the link instructions produced by rustc.

$ H5E_PATH=/tmp/html5ever
$ gcc -Wall -o tokenize tokenize.c -I $H5E_PATH/capi -L $H5E_PATH/build \
  -lhtml5ever_for_c -lrt -ldl -lpthread -lgcc_s -lpthread -lc -lm

$ ./tokenize 'Hello&comma; <i class=excellent>world!</i>'
CHARS : Hello
CHARS : ,
CHARS :  
TAG   : <i>
  ATTR: class="excellent"
CHARS : world!
TAG   : </i>

The build process is pretty standard for C; we just link a .a file and its dependencies. The biggest obstacle right now is that you won't find the Rust compiler in your distro's package manager, because the language is still changing so rapidly. But there's a ton of effort going into stabilizing the language for a Rust 1.0 release this year. It won't be too long before rustc is a reasonable build dependency.

Let's look at the C client code.

#include <stdio.h>

#include "html5ever.h"

void put_str(const char *x) {
    fputs(x, stdout);
}

void put_buf(struct h5e_buf text) {
    fwrite(text.data, text.len, 1, stdout);
}

void do_start_tag(void *user, struct h5e_buf name, int self_closing, size_t num_attrs) {
    put_str("TAG   : <");
    put_buf(name);
    if (self_closing) {
        putchar('/');
    }
    put_str(">\n");
}

// ...

struct h5e_token_ops ops = {
    .do_chars = do_chars,
    .do_start_tag = do_start_tag,
    .do_tag_attr = do_tag_attr,
    .do_end_tag = do_end_tag,
};

struct h5e_token_sink sink = {
    .ops = &ops,
    .user = NULL,
};

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("Usage: %s 'HTML fragment'\n", argv[0]);
        return 1;
    }

    struct h5e_tokenizer *tok = h5e_tokenizer_new(&sink);
    h5e_tokenizer_feed(tok, h5e_buf_from_cstr(argv[1]));
    h5e_tokenizer_end(tok);
    h5e_tokenizer_free(tok);
    return 0;
}

The struct h5e_token_ops contains pointers to callbacks. Any events we don't care to handle are left as NULL function pointers. Inside main, we create a tokenizer and feed it a string. html5ever for C uses a simple pointer+length representation of buffers, which is this struct h5e_buf you see being passed by value.

This demo only does tokenization, not tree construction. html5ever can perform both phases of parsing, but the API surface for tree construction is much larger and I didn't get around to writing C bindings yet.

Implementing the C API

Some parts of Rust's libstd depend on runtime services, such as task-local data, that a C program may not have initialized. So the first step in building a C API was to eliminate all std:: imports. This isn't nearly as bad as it sounds, because large parts of libstd are just re-exports from other libraries like libcore that we can use with no trouble. To be fair, I did write html5ever with the goal of a C API in mind, and I avoided features like threading that would be difficult to integrate. So your library might give you more trouble, depending on which Rust features you use.

The next step was to add the #![no_std] crate attribute. This means we no longer import the standard prelude into every module. To compensate, I added use core::prelude::*; to most of my modules. This brings in the parts of the prelude that can be used without runtime system support. I also added many imports for ubiquitous types like String and Vec, which come from libcollections.

After that I had to get rid of the last references to libstd. The biggest obstacle here involved macros and deriving, which would produce references to names under std::. To work around this, I create a fake little mod std which re-exports the necessary parts of core and collections. This is similar to libstd's "curious inner-module".

I also had to remove all uses of format!(), println!(), etc., or move them inside #[cfg(not(for_c))]. I needed to copy in the vec!() macro which is only provided by libstd, even though the Vec type is provided by libcollections. And I had to omit debug log messages when building for C; I did this with conditionally-defined macros.

With all this preliminary work done, it was time to write the C bindings. Here's how the struct of function pointers looks on the Rust side:

#[repr(C)]
pub struct h5e_token_ops {
    do_start_tag: extern "C" fn(user: *mut c_void, name: h5e_buf,
        self_closing: c_int, num_attrs: size_t),
    
    do_tag_attr: extern "C" fn(user: *mut c_void, name: h5e_buf,
        value: h5e_buf),

    do_end_tag:  extern "C" fn(user: *mut c_void, name: h5e_buf),

    // ...
}

The processing of tokens is straightforward. We pattern-match and then call the appropriate function pointer, unless that pointer is NULL. (Edit: eddyb points out that storing NULL as an extern "C" fn is undefined behavior. Better to use Option<extern "C" fn ...>, which will optimize to the same one-word representation.)

To create a tokenizer, we heap-allocate the Rust data structure in a Box, and then transmute that to a raw C pointer. When the C client calls h5e_tokenizer_free, we transmute this pointer back to a box and drop it, which will invoke destructors and finally free the memory.

You'll note that the functions exported to C have several special annotations:

  • #[no_mangle]: skip name mangling, so we end up with a linker symbol named h5e_tokenizer_free instead of _ZN5for_c9tokenizer18h5e_tokenizer_free.
  • unsafe: don't let Rust code call these functions unless it promises to be careful.
  • extern "C": make sure the exported function has a C-compatible ABI. The data structures similarly get a #[repr(C)] attribute.

Then I wrote a C header file matching this ABI:

struct h5e_buf {
    unsigned char *data;
    size_t len;
};

struct h5e_buf h5e_buf_from_cstr(const char *str);

struct h5e_token_ops {
    void (*do_start_tag)(void *user, struct h5e_buf name,
        int self_closing, size_t num_attrs);

    void (*do_tag_attr)(void *user, struct h5e_buf name,
        struct h5e_buf value);

    void (*do_end_tag)(void *user, struct h5e_buf name);

    /// ...
};

struct h5e_tokenizer;

struct h5e_tokenizer *h5e_tokenizer_new(struct h5e_token_sink *sink);
void h5e_tokenizer_free(struct h5e_tokenizer *tok);
void h5e_tokenizer_feed(struct h5e_tokenizer *tok, struct h5e_buf buf);
void h5e_tokenizer_end(struct h5e_tokenizer *tok);

One remaining issue is that Rust is hard-wired to use jemalloc, so linking html5ever will bring that in alongside the system's libc malloc. Having two separate malloc heaps will likely increase memory consumption, and it prevents us from doing fun things like allocating Boxes in Rust that can be used and freed in C. Before Rust can really be a great choice for writing C libraries, we need a better solution for integrating the allocators.

If you'd like to talk about calling Rust from C, you can find me as kmc in #rust and #rust-internals on irc.mozilla.org. And if you run into any issues with html5ever, do let me know, preferably by opening an issue on GitHub. Happy hacking!

83 comments:

  1. html5ever/macros/src/named_entities.rs:74:68: 74:77 error: explicit lifetime bound required

    are you using the stable .11?

    ReplyDelete
  2. I must say you had done a tremendous job,I appreciate all your efforts.Thanks alot for your writings......Waiting for a new 1...Please visit our wonderful and valuable website:
    Packers And Movers in Bangalore charges

    ReplyDelete
  3. Hi – It’s good to read such interesting content. I agree with much of what is written here and I’ll be coming back.
    Thanks again for posting such great reading material!! To get more relevant information visit here
    Packers And Movers Gurgaon
    Packers And Movers In Gurgaon charges

    ReplyDelete
  4. We Provide Best Packers And Movers Gurgaon List for Get Free Best Quotes, Compare Charges,
    Save Money And Time, Household Shifting Services @ http://packers-and-movers-gurgaon.in/
    Packers And Movers Bangalore to hyderabad

    ReplyDelete
  5. An excellent information provided thanks for all the information i must say great efforts made by you.
    thanks a lot for all the information you provided.
    please visit our official website for further details-
    Packers and Movers Delhi
    packers and movers noida

    ReplyDelete
  6. Packers and Movers
    Om Translogistics offers a host of services like house relocation, office relocation, industrial relocation, car carrier services and warehousing services.visit: Packers and Movers in India... Call us for more information 9910059708

    ReplyDelete


  7. الفك والتركيب والتغليف والتحرك من خلال شركة نقل اثاث بجدة متميزة تحتاج الي ركن البيت للاستفادة من خدماتها التي لا تقدم غير خدمات نقل اثاث بجدة رائعة لتلبية طلبات العميل. فرؤية الشركة لدينا وضعت طريقة جيدة وضعت كخبراء في نقل الخدمات التي يحتاجها العملاء عند التعاون مع شركة نقل عفش بجدة فاختيار المواد الخاصة بك التي تستخدم في تغليف الاثاث فهذه المواد أو الأشياء ستكون موجودة على عتبة المنزل للتحرك بكل آمن و بقوة إلى المكان الذي ترغب فيه
    شركة نقل الاثاث بالدمام
    استخدام الأصول الأولى داخل الاستراتيجية التي تستخدمها شركة نقل عفش بالدمام لدينا تدفعنا إلى التفكير في إعطاء نوع من الخدمات المتميزة الي العملاء التي تترك نجاحا مباشرا يمكن أن تنقش على نفسية الزبائن التي تقدم لهم خدمة نقل العفش.فلدينا ميل إلى أن يشار جيدا إلى العاملون والفنين والمغلفون ان يقوموا بعملهم في شركة نقل اثاث بالدمام نتيجة للمعيار والتنمية والعقل
    شركة نقل الاثاث بمكة
    مجموعة معينة لدينا في شركة نقل عفش بمكة تساعدنا في خدمتك في أي وقت من اليوم، وأنهم على استعداد للبقاء على طول هذه الخطوط لاعطاءك خدمة متميزة عن باقي شركات نقل اثاث بمكة التي توجد بهذه المنطقة فلا أحد لدينا في خدمات النقل يترك شيئا حتي لا نقع في قليلا من السخط.
    شركة تخزين الاثاث بالرياض
    التعبئة والتغليف يبدأ بالعمل المتميز من اجل الحصول علي شركة تخزين عفش بالرياض متميزة تمتلك مستودعات تخزين اثاث بالرياض تحافظ علي الممتلكات الخاصة بكم من الخراب. كما ان التعبئة والتغليف على استعداد فريد للتعامل مع كل نوع من الأدوات والأشياء الزجاجية والمواد التي تميل إلى الإضرار أو تحمل بانتظام أسوأ جزء في عملية الحركة. فخدمات شركة تخزين اثاث بالرياض تقوم بإرسال أفضل مجموعة يتقن الوصول إليها في الوقت المناسب لتلبية طلب العميل وفقا لمتطلبات محددة خاصة بك في هذا المجال بسبب الطريقة التي كانت لدينا مجموعة من الخبراء في كيفية ادارة مستودعات تخزين اثاث منذ فترة طويلة في هذه الصناعة لفترة طويلة جدا.
    شركة تخزين اثاث
    شركة تخزين عفش

    ReplyDelete
  8. Manish Packers and Movers Pvt Ltd as a Services providing company can make all the difference to your Home Relocation experience. Indore based Company which offers versatile solutions, Right team that easily reduce the stress associated with a Household Shifting, Vehicle Transportation. we help things run smoothly and reduce breakages and offer you seamless, Affordable, Reliable Shifting Services, Compare Shifting Charges, Visit :
    https://www.manishpackersmoversindore.in/
    https://www.manishpackersmoversindore.in/packers-and-movers-indore.html
    https://www.manishpackersmoversindore.in/manish-packers-and-movers-indore.html
    https://www.manishpackersmoversindore.in/packers-movers-gurgaon.html
    https://www.manishpackersmoversindore.in/packers-movers-kolkata.html
    https://www.manishpackersmoversindore.in/packers-movers-mumbai.html
    https://www.manishpackersmoversindore.in/packers-movers-bhopal.html
    https://www.manishpackersmoversindore.in/packers-movers-nagpur.html
    https://www.manishpackersmoversindore.in/packers-movers-raipur.html
    https://www.manishpackersmoversindore.in/packers-movers-ahmedabad.html

    ReplyDelete
  9. Hire Manish Packers and Movers Pvt Ltd in India for hassle-free Household Shifting, Office Relocation, Car Transporation, Loading Unloading, packing Unpacking at affordable Price Quotation. Top Rated Safe and Secure Service Providers who can help you with 24x7 and make sure a Untroubled Relocation Services at Cheapest/Lowest Rate. Visit More :-
    Manish Packers and Movers Pvt Ltd
    Movers and Packers Bangalore
    Movers and Packers Gurgaon
    Movers and Packers Indore
    Movers and Packers Kolkata
    Movers and Packers Mumbai
    Movers and Packers Nagpur
    Movers and Packers Ahmedabad
    Manish Packers in Indore
    Manish Packers and Movers Pvt Ltd Sitemap

    ReplyDelete
  10. Quickbooks POS Error 175305 is one of the investigate store trade error. Store trade is essentially exchange of information between your central station and Remote stores. Information which is sent between stores are frequently alluded as mailbag.

    ReplyDelete
  11. When one of the records to be refreshed is being used and can't be supplanted may be the reason for Quickbooks Payroll Error 15276. One of the basic errors looked by QuickBooks clients is QuickBooks Error code 15276. Beneath we will check causes and investigating ventures to settle QuickBooks Payroll Error 15276.

    ReplyDelete
  12. Quickbooks is the small business accounting software that's simple, smart and occasionally.QuickBooks is the secret to create an easy solution for errors.If you are faceing an issue in your accounting software so call our
    Quickbooks technical support phone number usa and fix the issue by our technical expert.

    ReplyDelete
  13. Many time new user hard to handle get more issue while using it. If you can looking any problem while working on it and need to help and you can choose best support service. We are here, our QuickBooks technical support centre is the right destination for a deal with your issue, we understand your problem. Our support team always assist you simply dial Quickbooks Enterprise Customer Phone Number 1888-557-6950 to get QuickBooks support.

    ReplyDelete
  14. There are many organizations that just can't work without a Point of Sale system and QuickBooks Point of Sale Support is a one-stop solution for all their problems. Quickbooks pos support phone number usa essentially contains both equipments as well as software.

    ReplyDelete
  15. Get help with your product by phone, email, or chat. QuickBooks Online Community. Get instant help, advice & answers from the QuickBooks Online Community.call our Intuit QuickBooks support and fix the issue by our technical expert.

    ReplyDelete
  16. Tatkal Railway Ticket Agent gives you the best cheap rate of railway ticket booking Chandigarh, railway ticket booking Chandigarh, Confirmed Tatkal Ticket Booking Chandigarh Call @ 9999606515.

    Tatkal Rail ticket agent

    train ticket agents in delhi

    confirm train book Chandigarh

    Railway Ticket Booking Agent

    ReplyDelete
  17. Love marriage specialist astrologer Pandit Hari Ram Ji provides a reputable person call @ 7837876237 with the best and authentic services in the love marriage astrology in India.

    Love Problem Solution ####
    Vashikaran Specialist ####
    Love Marriage Specialist ####
    Vashikaran For Love ####
    Vashikaran For Love ####
    Black Magic For Love ####

    ReplyDelete
  18. Ajay Shastri is the best Astrologer canada, he is the most prominent astrologer and Call Now +15875074472 gives accurate prediction about your future.

    Visit Now :-

    Astrologers in Canada ####
    http://www.astrologerincanada.ca/about-us.html ####
    http://www.astrologerincanada.ca/contact-us.html ####
    Astrologer in Brampton ####
    Astrologer in hamilton ####
    Astrologer in winnipeg ####
    Astrologer in Surrey ####

    ReplyDelete
  19. Ajay Shastri is the best Astrologer canada, he is the most prominent astrologer and Call Now +15875074472 gives accurate prediction about your future.

    Visit Now :-

    Astrologer in toronto ####
    Astrologer in vancouver ####
    Astrologer in ottawa ####
    Astrologer in calgary ####
    Astrologer in edmonton ####
    Astrologer in Montreal ####
    Love problem solution canada ####

    ReplyDelete
  20. There will be problems as well. Vashikaran Specialist In Mumbai But it might so Aghori ji happen that problems can be Call Now @ 9517888489.

    Visit Now :-

    Vashikaran specialist in surat ####
    Vashikaran specialist in Vadodara ####
    Vashikaran specialist in kolkata ####
    Vashikaran specialist in chandigarh ####
    Vashikaran specialist in jaipur ####

    ReplyDelete
  21. There will be problems as well. Vashikaran Specialist In Mumbai But it might so Aghori ji happen that problems can be Call Now @ 9517888489.

    Visit Now :-

    Vashikaran specialist in delhi ####
    Vashikaran specialist in mumbai ####
    Vashikaran specialist in pune ####
    Vashikaran specialist in bangalore ####
    Vashikaran specialist in hyderabad ####
    Vashikaran specialist in chennai ####

    ReplyDelete
  22. This ancient practice has not still lost its value and significance Aghori ji has so many uses in people’s life.(Call Now 9517888489).

    Visit Now :-

    Black magic specialist in Delhi ####
    Black magic specialist in pune ####
    Black magic specialist in mumbai ####
    Black magic specialist in Bangalore ####
    Black magic specialist in hyderaBad ####
    Black magic specialist in chennai ####
    Black magic specialist in surat ####

    ReplyDelete
  23. Hello everyone, if you want to get proper sexual satisfaction by our exoert and young girls. contact us on :-9873940964. you will be guaranteed satisfied. for get more details visit my website :-
    Nehru Place Escorts
    Pitampura Escorts

    ReplyDelete
  24. Connaught Place Escorts|9711199171 | Escorts Girls at your Hotel 24/7 Available


    connaught place escorts $$$$
    greater kailash escorts $$$$
    saket escorts $$$$
    dwarka escorts $$$$
    rohini escorts $$$$

    ReplyDelete
  25. Saket Call Girls | 9999965857 | Book Escorts in Saket at Hotels

    saket escorts $$$$$$
    mahipalpur escorts $$$$$$
    nagar escorts $$$$$$
    karol bagh escorts $$$$$$
    dwarka escorts $$$$$$

    ReplyDelete
  26. vasant kunj escorts ajency can give you the best escorts service so contact us 9873940964

    jangpura escorts ##
    mayur vihar escorts ##
    lodhi road escorts ##
    khan market escorts ##
    nizamuddin escorts ##
    greenpark escorts ##

    ReplyDelete
  27. Call now @ +1 5875074472 The best astrologer Ajay Shastri, Astrologer In Canada, will be more confident and able to make decisions to avoid those situations that can put you in trouble.


    Astrologer in toronto

    Astrologer in vancouver

    Astrologer in ottawa

    Astrologer in calgary

    Astrologer in edmonton

    Astrologer in Montreal

    Love problem solution canada

    ReplyDelete
  28. Call Now 9517888489 In these cases, there is no medicine to get successful results, a famous astrologer Aghori ji Vashikaran specialist In hyderabad and Black magic specialist In hyderabad can help you overcome your problem.

    Black magic specialist in surat ####
    Black magic specialist in vadodara ####
    Black magic specialist in jaipur ####
    Vashikaran specialist in bangalore ####
    Vashikaran specialist in chennai ####
    Vashikaran specialist in hyderabad ####

    ReplyDelete
  29. Do you require any assistant with QuickBooks Error 80070057 Support Number? QuickBooks Error 80070057 Support provides all types of QB Error support to the users. All error related issues of QuickBooks solved at QuickBooks Error Support Phone Number 1888-323-1555.

    ReplyDelete
  30. QuickBooks Technical Support Phone Number +1888-323-1555 is committed to providing round-the-clock support to manage your records provide users with the best services related to QB. QuickBooks Tech Support Number is a toll-free support number to support its clients.

    ReplyDelete
  31. vasant kunj Escorts for Gathering, Private & Get-togethers. Our Premium, Excellent and High-Class vasant kunj escorts will satisfy your dreams. An organization that offers Outcall benefits in all vasant kunj zones. Additionally, we offer modest vasant kunj escorts . Book now

    rohini escorts ##
    laxmi nagar escorts ##
    nehru place escorts ##
    lajpat nagar call girls ##
    karol bagh escorts ##
    greater kailash escorts ##
    ghaziabad escorts ##

    ReplyDelete
  32. Delhi Escorts Service available for bookings 9711199171 , Fulfill your sexual dream with Independent Call Girls Delhi, You can Hire Models vila Call Girls in Delhi for hotels and beaches. Fulfill your wish and find Independent Call Girls in Delhi.

    greater kailash escorts $$$
    preet vihar escorts $$$
    punjabi bagh escorts $$$
    pandav nagar escorts $$$
    patel nagar escorts $$$
    patparganj escorts $$$

    ReplyDelete
  33. Enjoy Vip Model Girls - Delhi Escorts Directly to your room. We provides Hot service to our clients. independent Delhi Escort available 24*7 working in Escort in Delhi cities.


    moti bagh call girls
    new friends colony call girls $$$
    okhla call girls $$$
    palam vihar call girls $$$
    paschim vihar call girls $$$
    preet vihar call girls $$$

    ReplyDelete
  34. This is the official page for Packers and Movers chandigarh. With the expertise in the packing and moving services, our branch at chandigarh has been professionally delivering satisfying outcomes the people across India.Call Us - 9001694151.

    packer and movers in chandigarh $$$$
    packer and movers chandigarh $$$$
    movers and packers chandigarh $$$$
    movers and packers in chandigarh $$$$
    http://www.chennaicargopackers.com/about-us.html $$$$
    http://www.chennaicargopackers.com/household-relocation-services.html $$$$
    http://www.chennaicargopackers.com/local-shifting-delhi.html $$$$

    ReplyDelete
  35. I'm riyapandey call girs in Faridabad.Faridabad escort agency give you out call and in call service.If you want book call girl visit here:-

    greater kailash escorts ##
    lajpat nagar escorts ##
    laxmi nagar escorts ##
    mahipalpur escorts ##
    malviya nagar escorts ##
    nehru place escorts ##

    ReplyDelete
  36. get exclusive night call girls in delhi. we provide only hot and sexy call girls in your location. all type of call girls are available. contact 9873777170 http://www.exclusivenightgirls.com/gallery-russian-escort-service-delhi.html
    connaught place escorts service💚

    💋lajpat nagar escorts service💚

    💋munirka escorts service💚

    💋east of kailash escorts service💚

    💋greater kailash escorts service💚

    💋hauz khas escorts service💚

    💋pitampura escorts service💚

    💋mayur vihar escorts service💚

    💋paharganj escorts service💚

    ReplyDelete
  37. I m your frequent reader! Today I got new info. & I enjoy it while reading.

    Vashikaran specialist astrologer

    Indian vashikaran expert

    ReplyDelete
  38. Very nice blog and articles. I am realy very happy to visit your blog. Now I am found which I actually want. I check your blog everyday and try to learn something from your blog. Thank you and waiting for your new post. Call Girls Darya Ganj , Call Girls Jama Masjid , Call Girls Kamla Market , Call Girls Lal kuan , Call Girls Gole Market , Call Girls Rabindra Nagar , Call Girls RK Puram

    ReplyDelete
  39. Always so interesting to visit your site.What a great info, thank you for sharing. this will help me so much in my learning.When your website or blog goes live for the first time, it is exciting. That is until you realize no one but you and your.Gtb Nagar Call Girls, Vaishali Call Girls, Indirapuram Call Girls, Crossings Republik Call Girls, Kaushambi Call Girls, Vasundhara Call Girls, Gaur City Call Girls, Nainital Call Girls Service

    ReplyDelete
  40. Love problem solution astrologer if you are finding a astrologer who can help you to get your love back or your partner back to you so don't worry you are in the right place
    Contact US +91-9587271222 Available On Whatsapp
    love problems solution
    love astrologer moulana barkat ali
    love problem solution astrologer in australia
    love marriage specialist
    Black magic Specialist
    Get LOve Back Astrologer
    Bring My Love back
    love vashikaran specialist
    Get My Girlfriend back







    ReplyDelete
  41. Love problem solution astrologer if you are finding a astrologer who can help you to get your love back or your partner back to you so don't worry you are in the right place
    cONTACT uS +91-7300107921 aVAILABLE oN wHATSAPP
    love vashikaran specialist
    Vashikaran mantra
    Online Love Astrology
    love Problem Solution Astrologer
    love Marriage Specialist Astrologer

    ReplyDelete
  42. Welcome to VIP Delhi Escorts, the escort agency with the excellent skills of love making. Our Call Girls service in Delhi can make anyone happy because we are available 24/7. You can feel free to call us: 9873940964 anytime.

    lajpat nagar escorts ###
    munirka escorts ###
    east of kailash escorts ###
    hauzkhas escorts ###
    pitampura escorts ###
    mayur vihar escorts ###
    paharganj escorts ###
    vasundhra escorts ###
    kaushambi escorts ###
    vaishali escorts ###

    ReplyDelete
  43. Independent noida Escorts | i am an independent call girl | you can visit me for fun. get full satisfaction. Call: 09873940964 | visit = http://anushkadas.in/contact.html noida Call Girls
    East Of Kailash Escorts

    Govindpuri Escorts

    Green Park Escorts

    Gtb Nagar Escorts

    Janakpuri Escorts

    Jj Colony Escorts

    Ajmeri Gate Escorts

    Anand Vihar Escorts

    Ashram Escorts

    ReplyDelete