Git Product home page Git Product logo

Comments (18)

raweden avatar raweden commented on May 30, 2024 2

Just as a Note in my example code above I where using WebCore::ScheduledAction which is not included within JSC.js by default. It has to be copied from the WebKit repo and be slightly modified to be independent from the rest of the WebCore library.

I plan on releasing the code written to bridge/implement the common minimum global scope, including Fetch API with streams somewhere in the future.

from jsc.js.

mbbill avatar mbbill commented on May 30, 2024
JSC >>> this
[object GlobalObject]

is that what you want?

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

I mean like javascript variables outside of the engine. Like if you have javascript code running outside the engine and you want a script to be able to access the variables outside of the engine.

from jsc.js.

mbbill avatar mbbill commented on May 30, 2024

Oh I see. Right now it's not supported yet because it needs by-directional communication between the outer and inner JS environment across web assembly, but that's definitely a useful feature.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

I'm trying to use this to obfuscate javascript. Is there any way to load in .jsc files directly? Like just straight javascript byte code?

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

Also how hard would it be for me to implement the jsc_eval code to access the normal js variables? Or do you know of any solutions that aren't that clean?

from jsc.js.

mbbill avatar mbbill commented on May 30, 2024

There is a way to do that. Actually I already have some initial work done. You may take a look at https://github.com/mbbill/JSC.js/blob/master/Source/JavaScriptCore/JSCJS/jscjs.cpp#L229
You can find some examples of compiling Javascript code into bytecode and using jsc.js to load and run bytecode.

There are still some issues though. The bytecode compiler doesn't handle 'new' operator correctly. It's due to one of the limit of early implementation of JSC byte cache. I'm not sure if they have fixed it or not.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

There is a way to do that. Actually I already have some initial work done. You may take a look at https://github.com/mbbill/JSC.js/blob/master/Source/JavaScriptCore/JSCJS/jscjs.cpp#L229
You can find some examples of compiling Javascript code into bytecode and using jsc.js to load and run bytecode.

There are still some issues though. The bytecode compiler doesn't handle 'new' operator correctly. It's due to one of the limit of early implementation of JSC byte cache. I'm not sure if they have fixed it or not.

Is there any way I can easily do that with the demo already setup? I just ripped the demo code and loaded in your jsc.wasm file for my own purposes. Does the demo js already support doing this or do I have to make modifications to it, or do I have to make modifications to the jsc.wasm code?

from jsc.js.

mbbill avatar mbbill commented on May 30, 2024

https://github.com/mbbill/JSC.js/blob/master/build/BUILD.gn#L151
the jsc_compile and jsc_eval_bytecode is already exported. You can try to test them with your existing setup.

jsc_compile is to convert JS to bytecode. and jsc_eval_bytecode is to run the previously generated bytecode.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

https://github.com/mbbill/JSC.js/blob/master/build/BUILD.gn#L151
the jsc_compile and jsc_eval_bytecode is already exported. You can try to test them with your existing setup.

jsc_compile is to convert JS to bytecode. and jsc_eval_bytecode is to run the previously generated bytecode.

How do I access them? I tried getCFunc and it only allows me to get "jsc_eval". Module only has "_jsc_eval".

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

As far as I can tell _jsc_compile and _jsc_eval_bytecode are not exported in the version used in your demo. I'll try to build it again but I still don't know why it won't work.

from jsc.js.

raweden avatar raweden commented on May 30, 2024

static bindings between the WASM environment and the Native JS engine can be added by using the C based JSC API, if one are only adding a few endpoints which calls function or setter/getters from/to either side.

// implementation of the function taking the JS call at WASM side.
JSValueRef setTimeoutCallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
    printf("setTimeoutCallAsFunction called with no. args: %zu\n", argumentCount);
    
    ExecState* exec = toJS(ctx);
    VM& vm = exec->vm();
    
    if(argumentCount < 1){
        // throw not-enough-arguments-error.
        return JSValueMakeUndefined(ctx);
    }

    JSC::JSValue arg1 = toJS(exec, arguments[0]);

    if(!arg1.isFunction(vm) && !arg1.isString()){
        // throw TypeError here
        return JSValueMakeUndefined(ctx);
    }

    JSC::JSValue arg2 = argumentCount > 1 ? toJS(exec, arguments[1]) : jsNumber(0);

    int delay = arg2.toUInt32(exec);

    std::unique_ptr<WebCore::ScheduledAction> action = WebCore::ScheduledAction::create(exec->lexicalGlobalObject(), JSC::Strong<JSC::Unknown> { vm, JSC::asObject(arg1) });
    
    int timeoutId = jsc_proxy_setTimeout(0, delay);
    globalTimerMap().set(timeoutId, WTFMove(action));
    return JSValueMakeNumber(ctx, timeoutId);
}

void setupCommonGlobalScope(JSGlobalObject* globalObject){

    JSContextRef ctx = toRef(globalObject->globalExec());

    // globalThis.setTimeout(func, [delay], [arg1, arg2 ...])
    JSStringRef nameString = JSStringCreateWithUTF8CString("setTimeout");
    JSObjectRef setTimeoutFn = JSObjectMakeFunctionWithCallback(ctx, nameString, setTimeoutCallAsFunction);
    JSObjectSetProperty(ctx, toRef(globalObject), nameString, setTimeoutFn, kJSPropertyAttributeNone, nullptr);
    JSStringRelease(nameString);
}

JSGlobalObject* jsc_global() {
    //jsc_init();
    //static VM& vm = VM::create(LargeHeap).leakRef();
    //JSLockHolder locker(vm);
    VM& vm = globalVM();
    
    static JSGlobalObject* globalObject = JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull()));
    globalObject->setRemoteDebuggingEnabled(true);

    JSContextRef ctx = toRef(globalObject->globalExec());

    // setting the name of the context (visable to inspector API)
    vm.vmEntryGlobalObject(globalObject->globalExec())->setName(String("default:jsc_global"));

    // Common Features in Global Scope (globalThis)
    setupCommonGlobalScope(globalObject);

    // console API, compile with `ENABLE_REMOTE_INSPECTOR=1` and uses custom RemoteInspector subclass, to bridge it to WASM host.
    static unique_ptr<RemoteConnectionToTarget> l_connectionToTarget = make_unique<RemoteConnectionToTarget>(globalObject->inspectorDebuggable());
    RemoteConnectionToTarget* connectionToTarget = l_connectionToTarget.get();
    connectionToTarget->setup(false, false);
    
    globalScriptContextMap().set(String("default"), globalObject);
    return globalObject;
}

Another approach is a fit all use cases; it should be possible to implement a custom VM wrapper, using the same wrapper protocol used to wrap Objective-C classes/object and binds those into the JS environment. This one would require a fair share of work. See the .mm files in /Source/JSC/API, glib GTK bindings also uses these API to bind classes/objects into the JS environment.

Another approach is to implement these types of bindings are to use proxy object which allows to respond with callback respond to any action applied to a object get/set/delete/has implement private endpoints in both environments and use a hash map to look these actions up, encoding/decoding primitives, reference objects in a hash map and wrapper callback/function the same way.

The hardest challenge with any approach is to make them work with the Garbage Collection at the hosting/native side.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

Interesting stuff. Thanks for the ideas and code. I will try to play around with this as soon as I can actually get this to compile. But for some reason it refuses on the linking JSC process at the end.

from jsc.js.

raweden avatar raweden commented on May 30, 2024

@TristonStuart It took some time getting the settings right for the build to get successful.. From those errors you posted in a previous issue, it seams like the ALWAYS_INLINE compile time defined is not recognised properly.

Add this line

        "ALWAYS_INLINE=inline",

into the file /JSC.js/build/BUILD.gn into the end of the defines in the section seen below:

config("compiler_defaults") {
    defines = [
        "JSCJS=1",
        "ENABLE_JIT=0",

There is a few more compile time defines that could be added (unrelated to your error):

        "ENABLE_WEBASSEMBLY=0",
        "USE_GENERIC_EVENT_LOOP=1",
        "ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS=0",
        "ENABLE_REMOTE_INSPECTOR=0,
        "LOG_DISABLED=0",
        "ENABLE_DEVELOPER_MODE=1",
        "HAVE_QOS_CLASSES=0", 

ENABLE_WEBASSEMBLY makes no sense to emulate WASM in WASM runtime.
USE_GENERIC_EVENT_LOOP controls the implementation of application runloop which is defined within the WTF (WebKit Template Framework).
ENABLE_REMOTE_INSPECTOR controls the behavior of the inspector, the default JSC.js code base don't have any implementation in place to use it, the code base controlled by the define is what enables for example console.log and the DevTools debugger (with breakpoints etc) seen within jsc/safari to work.
ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS is a sub settings for Remote Inspector.
LOG_DISABLED=0 enables some log statements.
ENABLE_DEVELOPER_MODE=1 more info in exceptions.
HAVE_QOS_CLASSES

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

@TristonStuart It took some time getting the settings right for the build to get successful.. From those errors you posted in a previous issue, it seams like the ALWAYS_INLINE compile time defined is not recognised properly.

Add this line

        "ALWAYS_INLINE=inline",

into the file /JSC.js/build/BUILD.gn into the end of the defines in the section seen below:

config("compiler_defaults") {
    defines = [
        "JSCJS=1",
        "ENABLE_JIT=0",

There is a few more compile time defines that could be added (unrelated to your error):

        "ENABLE_WEBASSEMBLY=0",
        "USE_GENERIC_EVENT_LOOP=1",
        "ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS=0",
        "ENABLE_REMOTE_INSPECTOR=0,
        "LOG_DISABLED=0",
        "ENABLE_DEVELOPER_MODE=1",
        "HAVE_QOS_CLASSES=0", 

ENABLE_WEBASSEMBLY makes no sense to emulate WASM in WASM runtime.
USE_GENERIC_EVENT_LOOP controls the implementation of application runloop which is defined within the WTF (WebKit Template Framework).
ENABLE_REMOTE_INSPECTOR controls the behavior of the inspector, the default JSC.js code base don't have any implementation in place to use it, the code base controlled by the define is what enables for example console.log and the DevTools debugger (with breakpoints etc) seen within jsc/safari to work.
ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS is a sub settings for Remote Inspector.
LOG_DISABLED=0 enables some log statements.
ENABLE_DEVELOPER_MODE=1 more info in exceptions.
HAVE_QOS_CLASSES

This works perfectly. The code was able to compile and run perfectly. Thank you so much. I am looking forward to seeing you add global access as I think this project could be used for js security. I would make a pull request and add those changes.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

Just as a Note in my example code above I where using WebCore::ScheduledAction which is not included within JSC.js by default. It has to be copied from the WebKit repo and be slightly modified to be independent from the rest of the WebCore library.

I plan on releasing the code written to bridge/implement the common minimum global scope, including Fetch API with streams somewhere in the future.

Have you made a working prototype?

from jsc.js.

raweden avatar raweden commented on May 30, 2024

Have you made a working prototype?

Its about halfway implemented, written in c++ for performance reasons. I looked at merge these parts from WebCore, but its hard work as its hard to just pull out certain parts of from that code base, and these JavaScript API written for WebCore part of Webkit is also written in predefined JS, which in native Safari don't matter as it JIT compiles it anyways, this is not possible in JSC which requires a different approach of implementing it to squeeze out the most performance.

from jsc.js.

TristonStuart avatar TristonStuart commented on May 30, 2024

It sounds very complicated. If you make a working version I would love to include it in the wrapper API I wrote. I think this project can go a long way to help protect javascript code security.

from jsc.js.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.