Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

access violation with call_with_this #21

Closed
ctaggart opened this issue Sep 3, 2017 · 9 comments
Closed

access violation with call_with_this #21

ctaggart opened this issue Sep 3, 2017 · 9 comments

Comments

@ctaggart
Copy link

ctaggart commented Sep 3, 2017

I'm trying to use call_with_this like in #20, but I'm getting an access violation exception. If I choose to debug into it with Visual Studio, it shows this:

image

The code to reproduce is here:
https://github.com/ctaggart/typescript_ts/pull/2/files#diff-6382a243b48dc8580db0fb4e2fb6e26f
cargo run --example create

I'm using ChakraCore v1.7.0.

@ctaggart
Copy link
Author

ctaggart commented Sep 6, 2017

@darfink, ideas for how I can troubleshoot this? Is this my misunderstanding of lifetimes in Rust? I'll see about reproducing it in a short single script that I can paste here.

@ctaggart
Copy link
Author

ctaggart commented Sep 6, 2017

This works just fine, so my guess is that I'm doing something wrong with the guard and lifetimes.

extern crate chakracore;

use std::io::prelude::*;
use std::fs::File;

fn main() {
    let runtime = chakracore::Runtime::new().unwrap();
    let context = chakracore::Context::new(&runtime).unwrap();
    let guard = context.make_current().unwrap();

    // load typescript.js
    let js = "./node_modules/typescript/lib/typescript.js";
    let mut file = File::open(js).expect("unable to open the file");
    let mut contents = String::new();
    file.read_to_string(&mut contents).expect("unable to read the file");
    chakracore::script::eval(&guard, &contents).expect("invalid JavaScript code");

    // get ts variable
    let ts = guard.global().get(&guard, &chakracore::Property::new(&guard, "ts")).into_object().unwrap();

    // call createNode
    let function = ts.get(&guard, &chakracore::Property::new(&guard, "createNode")).into_function().unwrap();
    println!("got function createNode");
    let rv = function.call_with_this(&guard, &ts, &[
        &chakracore::value::Number::new(&guard, 3).into(),
        &chakracore::value::Number::new(&guard, -1).into(),
        &chakracore::value::Number::new(&guard, -1).into(),
    ]);
    println!("rv: {:?}", rv);
    let node = rv.unwrap().into_object().unwrap();

    // verify that the node kind is 3
    let kind = node.get(&guard, &chakracore::Property::new(&guard, "kind"));
    println!("kind: {:?}", kind);

}

@ctaggart
Copy link
Author

ctaggart commented Sep 6, 2017

If I introduce a struct that contains the guard, this blows up with the error. I'm not sure what I'm doing wrong with lifetimes yet.

extern crate chakracore;

use std::io::prelude::*;
use std::fs::File;

pub struct Js<'a> {
    guard: &'a chakracore::context::ContextGuard<'a>,
}

impl<'a> Js<'a> {
    pub fn new(guard: &'a chakracore::context::ContextGuard<'a>) -> Js<'a> {
        let js = "./node_modules/typescript/lib/typescript.js";
        let mut file = File::open(js).expect("unable to open the file");
        let mut contents = String::new();
        file.read_to_string(&mut contents).expect("unable to read the file");
        chakracore::script::eval(&guard, &contents).expect("invalid JavaScript code");
        Js { guard: guard }
    }
}

fn main() {
    let runtime = chakracore::Runtime::new().unwrap();
    let context = chakracore::Context::new(&runtime).unwrap();
    let guard = context.make_current().unwrap();

    let js = Js::new(&guard);
    let ts = js.guard.global().get(js.guard, &chakracore::Property::new(js.guard, "ts")).into_object().unwrap();
    
    // call createNode
    let function = ts.get(js.guard, &chakracore::Property::new(js.guard, "createNode")).into_function().unwrap();
    println!("got function createNode");
    let rv = function.call_with_this(js.guard, &ts, &[
        &chakracore::value::Number::new(js.guard, 3).into(),
        &chakracore::value::Number::new(js.guard, -1).into(),
        &chakracore::value::Number::new(js.guard, -1).into(),
    ]);
    println!("rv: {:?}", rv);
}

@ctaggart
Copy link
Author

ping @darfink

@ctaggart
Copy link
Author

ctaggart commented Oct 9, 2017

If I pass in the ContextGuard to every function, I don't run into problems. It makes the API a bit more difficult to use, but I could probably live with it. I blogged about wrapping the TypeScript API here:

http://blog.ctaggart.com/2017/10/creating-and-printing-typescript-ast.html

@darfink
Copy link
Owner

darfink commented Mar 6, 2018

I understand this is a belated solution, but I've identified the culprit.

The issue was never due to the lifetime introduced in conjunction with the ContextGuard, but that the contents of the source file was freed when the lexical scope exited, in this case freeing the contents variable.

Due to my previous experience with V8, I assumed ChakraCore behaved likewise regarding the parsing and execution of external JavaScript source code. Therefore I expected JsRun to parse the entire supplied source code, rendering it as a non-dependency.

I've created a fix for this by allocating a JsString instead, making ChakraCore responsible for managing the files' contents.

@darfink
Copy link
Owner

darfink commented Mar 7, 2018

Fixed with ac890b4

@darfink darfink closed this as completed Mar 7, 2018
ctaggart added a commit to ctaggart/typescript_ts that referenced this issue Mar 14, 2018
@ctaggart
Copy link
Author

Thanks @darfink! It works great.

ctaggart added a commit to ctaggart/typescript_ts that referenced this issue Mar 14, 2018
* put the context in objects
now that darfink/chakracore-rs#21 is fixed

* node.kind() works

* enum as i32

* began converting evertying to structs

* began converts everything to structs

* all as_* "casts"

* fix temporary value does not live long enough

* fixed other lifetime

* create_source works again
@ctaggart
Copy link
Author

I revised my prototype today and blogged about it. It works a lot better with this fixed.
http://blog.ctaggart.com/2018/03/creating-and-printing-typescript-ast.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants