Skip to content

Instantly share code, notes, and snippets.

@bensu
Last active August 29, 2015 14:19
Show Gist options
  • Save bensu/8c16efbe86bcda82f99d to your computer and use it in GitHub Desktop.
Save bensu/8c16efbe86bcda82f99d to your computer and use it in GitHub Desktop.
Minimal failing case for core.cljs
This Gist shows a potential bug in nashorn 1.8.0_40/1.8.0_45. It works properly in Java 9. It was logged with Review ID: JI-9020683.
After compiling a reduced version of core.cljs (the ClojureScript language) and a minimal test,
V8 and Spidermonkey print 1 and 10 when the compiled script runs. Nashorn prints 1 and then throws
the custom exception "Error: No protocol method IDeref defined for type :[object Object]"
The file compiled.js is a distilled version of the real compiled file that has the minimum code to
fail. Any of the lines marked with // X solve the problem when deleted for 1.8.0_40. Deleting the
commented function solves the problem both for 1.8.0_40 and 1.8.0_45. Said function is not referenced
in the code at all.
namespace = {};
namespace.deref = function(o) {
if (o.internal_deref != undefined) {
return o.internal_deref(o);
} else {
throw Error(["No protocol method IDeref defined for type :", o].join(""));
}
};
namespace.Volatile = function(state) {
this.state = state;
this.internal_symbol1 = 32768; // X
this.internal_symbol2 = 0; // X
};
namespace.Volatile.prototype.vreset = function(_, new_state) {
var self__ = this;
return self__.state = new_state;
}; // this function is never called, yet deleting results in correct behavior
namespace.Volatile.prototype.internal_deref = function(_) {
var self__ = this;
return self__.state;
};
print(function() {
var v = new namespace.Volatile(1);
return namespace.deref.call(null, v);
}());
namespace.MyCustomAtom = function(state) {
this.state = state;
this.internal_symbol1 = 32768; // X
this.internal_symbol2 = 0; // X
};
namespace.MyCustomAtom.prototype.internal_deref = function(_) {
var self__ = this;
return self__.state;
};
print(function() {
var customAtom = new namespace.MyCustomAtom(10);
return namespace.deref.call(null, customAtom);
}());
(ns cljs.core)
(defn missing-protocol [proto obj]
(js/Error.
(.join (array "No protocol method " proto
" defined for type :" obj) "")))
(defprotocol IDeref
(-deref [o]))
(defprotocol IVolatile
(-vreset! [o new-value]))
(deftype Volatile [^:mutable state]
IVolatile ;; If I Volatile is removed, then it works
(-vreset! [_ new-state]
(set! state new-state))
IDeref
(-deref [_] state))
(ns cljs.core-test)
(js/print (let [v (Volatile. 1)]
(-deref v)))
(deftype MyCustomAtom [state]
IDeref
(-deref [_] state))
(js/print (let [a0 (MyCustomAtom. 10)]
(-deref a0)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment