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

Implement the preserveWrapperCallback API to allow our DOM objects to be stored in WeakMaps. #7218

Closed
nickdesaulniers opened this issue Aug 14, 2015 · 15 comments
Labels
A-content/bindings The DOM bindings A-content/dom Interacting with the DOM from web content I-crash No impact; the issue is one of maintainability or tidiness.

Comments

@nickdesaulniers
Copy link

➜  servo git:(master) ✗ RUST_BACKTRACE=1 ./build/servo http://localhost:4000
Error at http://localhost:4000/dist.js:27: TypeError: document.createElement(...).getContext is not a function

evaluate_script failed

Not sure if getContext is not a method of an HTMLCanvasElement, or if createElement is not a method of the document object?

@jdm
Copy link
Member

jdm commented Aug 14, 2015

Both of those exist and are tested. What is the code that isn't working?

http://mxr.mozilla.org/servo/source/components/script/dom/htmlcanvaselement.rs#241

@nox nox added A-content/dom Interacting with the DOM from web content S-awaiting-answer Someone asked a question that requires an answer. labels Aug 15, 2015
@nickdesaulniers
Copy link
Author

@jdm
Copy link
Member

jdm commented Aug 28, 2015

Assertion failure: cx->runtime()->preserveWrapperCallback, at /Users/jdm/.cargo/git/checkouts/mozjs-06d7f04b6dbb8a8e/master/mozjs/js/src/jsweakmap.cpp:332
Process 47230 stopped
* thread #7: tid = 0xac5c7, 0x0000000102329347 servo`TryPreserveReflector(cx=0x000000010a41cc40, obj=JS::HandleObject at 0x000000011a9f3720) + 263 at jsweakmap.cpp:332, name = 'ScriptTask PipelineId(0)', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000102329347 servo`TryPreserveReflector(cx=0x000000010a41cc40, obj=JS::HandleObject at 0x000000011a9f3720) + 263 at jsweakmap.cpp:332
   329          (obj->is<ProxyObject>() &&
   330           obj->as<ProxyObject>().handler()->family() == GetDOMProxyHandlerFamily()))
   331      {
-> 332          MOZ_ASSERT(cx->runtime()->preserveWrapperCallback);
   333          if (!cx->runtime()->preserveWrapperCallback(cx, obj)) {
   334              JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_WEAKMAP_KEY);
   335              return false;
(lldb) bt
error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0
* thread #7: tid = 0xac5c7, 0x0000000102329347 servo`TryPreserveReflector(cx=0x000000010a41cc40, obj=JS::HandleObject at 0x000000011a9f3720) + 263 at jsweakmap.cpp:332, name = 'ScriptTask PipelineId(0)', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000102329347 servo`TryPreserveReflector(cx=0x000000010a41cc40, obj=JS::HandleObject at 0x000000011a9f3720) + 263 at jsweakmap.cpp:332
    frame #1: 0x0000000102303b9c servo`SetWeakMapEntryInternal(cx=0x000000010a41cc40, mapObj=Handle<js::WeakMapObject *> at 0x000000011a9f3810, key=JS::HandleObject at 0x000000011a9f3808, value=JS::HandleValue at 0x000000011a9f3800) + 236 at jsweakmap.cpp:368
    frame #2: 0x0000000102349825 servo`WeakMap_set_impl(cx=0x000000010a41cc40, args=CallArgs at 0x000000011a9f3990) + 789 at jsweakmap.cpp:405
    frame #3: 0x000000010233bb2f servo`bool JS::CallNonGenericMethod<&(cx=0x000000010a41cc40, args=CallArgs at 0x000000011a9f3a10)), &(WeakMap_set_impl(JSContext*, JS::CallArgs))>(JSContext*, JS::CallArgs) + 127 at CallNonGenericMethod.h:100
    frame #4: 0x0000000102303414 servo`js::WeakMap_set(cx=0x000000010a41cc40, argc=2, vp=0x000000010b876668) + 100 at jsweakmap.cpp:415
    frame #5: 0x0000000101b6d9eb servo`js::CallJSNative(cx=0x000000010a41cc40, native=0x00000001023033b0, args=0x000000011a9f4340)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) + 187 at jscntxtinlines.h:235
    frame #6: 0x0000000101b27c15 servo`js::Invoke(cx=0x000000010a41cc40, args=CallArgs at 0x000000011a9f4340, construct=NO_CONSTRUCT) + 1269 at Interpreter.cpp:502
    frame #7: 0x0000000101b41030 servo`Interpret(cx=0x000000010a41cc40, state=0x000000011a9f7218) + 51744 at Interpreter.cpp:2609
    frame #8: 0x0000000101b34529 servo`js::RunScript(cx=0x000000010a41cc40, state=0x000000011a9f7218) + 585 at Interpreter.cpp:452
    frame #9: 0x0000000101b27d56 servo`js::Invoke(cx=0x000000010a41cc40, args=CallArgs at 0x000000011a9f7a10, construct=NO_CONSTRUCT) + 1590 at Interpreter.cpp:521
    frame #10: 0x000000010222cf11 servo`js::fun_call(cx=0x000000010a41cc40, argc=8, vp=0x000000010b876218) + 577 at jsfun.cpp:1239
    frame #11: 0x0000000101b6d9eb servo`js::CallJSNative(cx=0x000000010a41cc40, native=0x000000010222ccd0, args=0x000000011a9f83d0)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) + 187 at jscntxtinlines.h:235
    frame #12: 0x0000000101b27c15 servo`js::Invoke(cx=0x000000010a41cc40, args=CallArgs at 0x000000011a9f83d0, construct=NO_CONSTRUCT) + 1269 at Interpreter.cpp:502
    frame #13: 0x0000000101b41030 servo`Interpret(cx=0x000000010a41cc40, state=0x000000011a9fb2e0) + 51744 at Interpreter.cpp:2609
    frame #14: 0x0000000101b34529 servo`js::RunScript(cx=0x000000010a41cc40, state=0x000000011a9fb2e0) + 585 at Interpreter.cpp:452
    frame #15: 0x0000000101b4d6bd servo`js::ExecuteKernel(cx=0x000000010a41cc40, script=JS::HandleScript at 0x000000011a9fb408, scopeChainArg=0x000000011a356060, thisv=0x000000011a9fb480, type=EXECUTE_GLOBAL, evalInFrame=(ptr_ = 0), result=0x000000011a9fc040) + 1149 at Interpreter.cpp:660
    frame #16: 0x0000000101b4db07 servo`js::Execute(cx=0x000000010a41cc40, script=JS::HandleScript at 0x000000011a9fb4f0, scopeChainArg=0x000000011a356060, rval=0x000000011a9fc040) + 999 at Interpreter.cpp:702
    frame #17: 0x000000010217af55 servo`Evaluate(cx=0x000000010a41cc40, scope=JS::HandleObject at 0x000000011a9fb770, optionsArg=0x000000010a41bf10, srcBuf=0x000000011a9fb7d0, rval=JS::MutableHandleValue at 0x000000011a9fb768) + 1029 at jsapi.cpp:4183
    frame #18: 0x000000010217b2b4 servo`Evaluate(cx=0x000000010a41cc40, optionsArg=0x000000010a41bf10, chars=0x000000011b0ac000, length=77783, rval=JS::MutableHandleValue at 0x000000011a9fb808) + 132 at jsapi.cpp:4218
    frame #19: 0x000000010217b21d servo`JS::Evaluate(cx=0x000000010a41cc40, optionsArg=0x000000010a41bf10, chars=0x000000011b0ac000, length=77783, rval=JS::MutableHandleValue at 0x000000011a9fb848) + 61 at jsapi.cpp:4272
    frame #20: 0x00000001018ddf7f servo`js::jsapi::Evaluate2(cx=0x000000010a41cc40, options=0x000000010a41bf10, chars=0x000000011b0ac000, length=77783, rval=MutableHandle<js::jsapi::Value> at 0x000000011a9fb8a0) + 111 at jsapi.rs:8981
    frame #21: 0x00000001018ddf05 servo`jsapi::Evaluate2::he412378402173c2eqoi + 37
    frame #22: 0x0000000100c27bb5 servo`script::dom::window::&'a T.ScriptHelpers::evaluate_script_on_global_with_result(self=0x000000011b042600, code=(data_ptr = "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = function (gl, data, elemPerVertex, attribute) {\n  var buffer = gl.createBuffer();\n  if (!buffer) throw new Error('Failed to create buffer.');\n  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n  gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);\n  gl.vertexAttribPointer(attribute, elemPerVertex, gl.FLOAT, false, 0, 0);\n  gl.enableVertexAttribArray(attribute);\n  return buffer;\n};\n\n\n},{}],2:[function(require,module,exports){\n// watchify main.js -o dist.js -v -d\n\nvar glShader = require('gl-shader');\nvar createQuat = require('gl-q...", length = 77783), filename=(data_ptr = "file:///Users/jdm/Downloads/demo/dist.js", length = 40), rval=MutableHandle<js::jsapi::Value> at 0x000000011a9fbc78) + 1429 at window.rs:632
    frame #23: 0x0000000101190e2c servo`script::dom::htmlscriptelement::HTMLScriptElement::execute(self=0x000000011b067000, load=ScriptOrigin at 0x000000011a9fc3a8) + 3436 at htmlscriptelement.rs:405
    frame #24: 0x000000010118f0e6 servo`script::dom::htmlscriptelement::ScriptContext.AsyncResponseListener::response_complete(self=0x000000011b042c18, status=Result<(), collections::string::String> at 0x000000011a9fcad8) + 390 at htmlscriptelement.rs:170
    frame #25: 0x000000010155c776 servo`net_traits::ResponseAction::process(self=ResponseAction at 0x000000011a9fcd68, listener=&AsyncResponseListener at 0x000000011a9fcd58) + 502 at lib.rs:120
    frame #26: 0x00000001011989a6 servo`script::network_listener::ListenerRunnable<T>.Runnable::handler(self=0x0000000114036880) + 502 at network_listener.rs:47
    frame #27: 0x000000010131f51c servo`script::script_task::ScriptTask::handle_msg_from_script(self=0x000000011aa00450, msg=MainThreadScriptMsg at 0x000000011a9fd590) + 636 at script_task.rs:918
    frame #28: 0x00000001013277cb servo`script::script_task::ScriptTask::handle_msgs(self=0x000000011aa00450) + 7515 at script_task.rs:825
    frame #29: 0x000000010131c571 servo`script::script_task::ScriptTask::start(self=0x000000011aa00450) + 33 at script_task.rs:684
    frame #30: 0x000000010131c53d servo`fnfn + 29 at script_task.rs:491
    frame #31: 0x000000010131c2b1 servo`script::mem::ProfilerChan::run_with_memory_reporting<closure,fn(self=0x000000011aa00788, f=closure at 0x000000011a9ffcf0, reporter_name=String at 0x000000011a9ffcd8, channel_for_reporter=Box<ScriptChan> at 0x000000011a9ffcc8, msg=0x0000000101062570) -> script::script_task::CommonScriptMsg,script::script_task::CommonScriptMsg,Box<ScriptChan>> + 577 at mem.rs:61
    frame #32: 0x0000000101312a0a servo`fnfn + 3258 at script_task.rs:490
    frame #33: 0x0000000101311cb8 servo`fnfn + 104 at task.rs:31
    frame #34: 0x0000000101311c08 servo`script::boxed::F.FnBox<A>::call_box(self=0x0000000116842280, args=<unavailable>) + 104 at boxed.rs:512
    frame #35: 0x0000000100bec34c servo`script::boxed::Box<FnBox<A, Output = R>+ Send + 'a>.FnOnce<A>::call_once(self=Box<FnBox<()>> at 0x000000011aa00bc0, args=<unavailable>) + 60 at boxed.rs:528
    frame #36: 0x0000000100bebf2e servo`fnfn + 78 at mod.rs:309
    frame #37: 0x0000000100bebeda servo`script::rt::unwind::try::try_fn<closure>(opt_closure=0x000000011aa00cf0) + 58 at mod.rs:164
    frame #38: 0x000000010281cce9 servo`__rust_try + 9
    frame #39: 0x0000000102818941 servo`rt::unwind::try::inner_try::h39d984f71e9cc780Tyw + 97
    frame #40: 0x0000000100bebe44 servo`script::rt::unwind::try<closure>(f=closure at 0x000000011aa00d08) + 100 at mod.rs:136
    frame #41: 0x0000000100bebcbc servo`fnfn + 412 at mod.rs:309
    frame #42: 0x0000000100bec5ad servo`script::boxed::F.FnBox<A>::call_box(self=0x0000000116824160, args=<unavailable>) + 77 at boxed.rs:512
    frame #43: 0x000000010281bfde servo`sys::thread::Thread::new::thread_start::h999b3790b6d4b23deXv + 142
    frame #44: 0x00007fff928ae899 libsystem_pthread.dylib`_pthread_body + 138
    frame #45: 0x00007fff928ae72a libsystem_pthread.dylib`_pthread_start + 137
    frame #46: 0x00007fff928b2fc9 libsystem_pthread.dylib`thread_start + 13

@jdm
Copy link
Member

jdm commented Aug 28, 2015

Looks like we need to implement the preserveWrapperCallback API to allow our DOM objects to be stored in WeakMaps.

@jdm jdm added the A-content/bindings The DOM bindings label Aug 28, 2015
@nox
Copy link
Contributor

nox commented Aug 30, 2015

WeakMaps? Where are they? Do they do what I think they do? Can we use them from Rust for ranges and things like that?

@jdm
Copy link
Member

jdm commented Aug 30, 2015

They're SpiderMonkey things. I don't even know the situation for using them from C++, let alone Rust.

@jdm
Copy link
Member

jdm commented Aug 30, 2015

@jdm jdm removed the S-awaiting-answer Someone asked a question that requires an answer. label Aug 30, 2015
@Ms2ger Ms2ger changed the title Unable to get a WebGL context Implement the preserveWrapperCallback API to allow our DOM objects to be stored in WeakMaps. Sep 14, 2015
@Ms2ger Ms2ger added the I-crash No impact; the issue is one of maintainability or tidiness. label Sep 14, 2015
@Ms2ger
Copy link
Contributor

Ms2ger commented Sep 14, 2015

This involves calling js::jsapi::SetPreserveWrapperCallback in ScriptTask::new_rt_and_cx() (components/script/script_task.rs). The argument should be a new preserve_wrapper function that unconditionally returns true.

@Ms2ger Ms2ger added the E-less-complex Straightforward. Recommended for a new contributor. label Sep 14, 2015
@Ms2ger
Copy link
Contributor

Ms2ger commented Sep 14, 2015

... as well as adding tests in window and worker contexts.

@jdm
Copy link
Member

jdm commented Sep 14, 2015

#7620 has a great testcase for the window context that we can copy.

@Manishearth
Copy link
Member

Minimimized GitHub testcase:

<html><head></head><body>
<input id="a">
    <script type="text/javascript">
    x = new WeakMap();
    x.set(document.getElementById("a"), 2);
    </script>
</body></html>

@Manishearth
Copy link
Member

@jdm Also, rust-mozjs expects a function returning a u8, whereas actually it is -> bool. I'm not sure if that part is autogenerated, but should we fix that?

@jdm
Copy link
Member

jdm commented Sep 15, 2015

I do not know anything about the implications of using bool/u8 in FFI, unfortunately.

@Ms2ger
Copy link
Contributor

Ms2ger commented Sep 16, 2015

Use JSTrue for now.

Manishearth added a commit to Manishearth/servo that referenced this issue Sep 17, 2015
@Manishearth Manishearth removed the E-less-complex Straightforward. Recommended for a new contributor. label Sep 17, 2015
@Manishearth
Copy link
Member

A naive return JSTrue impl of this seems to segfault a lot. Not E-Easy.

Manishearth added a commit to Manishearth/servo that referenced this issue Sep 23, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-content/bindings The DOM bindings A-content/dom Interacting with the DOM from web content I-crash No impact; the issue is one of maintainability or tidiness.
Projects
None yet
Development

No branches or pull requests

6 participants