예제 #1
0
bool
SavedStacks::insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandle<SavedFrame*> frame)
{
    if (iter.done()) {
        frame.set(nullptr);
        return true;
    }

    ScriptFrameIter thisFrame(iter);
    Rooted<SavedFrame*> parentFrame(cx);
    if (!insertFrames(cx, ++iter, &parentFrame))
        return false;

    RootedScript script(cx, thisFrame.script());
    RootedFunction callee(cx, thisFrame.maybeCallee());
    const char *filename = script->filename();
    RootedAtom source(cx, Atomize(cx, filename, strlen(filename)));
    if (!source)
        return false;
    uint32_t column;
    uint32_t line = PCToLineNumber(script, thisFrame.pc(), &column);

    SavedFrame::Lookup lookup(source,
                              line,
                              column,
                              callee ? callee->displayAtom() : nullptr,
                              parentFrame,
                              thisFrame.compartment()->principals);

    frame.set(getOrCreateSavedFrame(cx, lookup));
    return frame.address() != nullptr;
}
예제 #2
0
bool
js::XDRScriptRegExpObject(XDRState<mode>* xdr, MutableHandle<RegExpObject*> objp)
{
    /* NB: Keep this in sync with CloneScriptRegExpObject. */

    RootedAtom source(xdr->cx());
    uint32_t flagsword = 0;

    if (mode == XDR_ENCODE) {
        MOZ_ASSERT(objp);
        RegExpObject& reobj = *objp;
        source = reobj.getSource();
        flagsword = reobj.getFlags();
    }
    if (!XDRAtom(xdr, &source) || !xdr->codeUint32(&flagsword))
        return false;
    if (mode == XDR_DECODE) {
        RegExpFlag flags = RegExpFlag(flagsword);
        RegExpObject* reobj = RegExpObject::createNoStatics(xdr->cx(), source, flags, nullptr,
                                                            xdr->cx()->tempLifoAlloc());
        if (!reobj)
            return false;

        objp.set(reobj);
    }
    return true;
}
예제 #3
0
static bool
GetSharedTypedArray(JSContext* cx, HandleValue v,
                    MutableHandle<SharedTypedArrayObject*> viewp)
{
    if (!v.isObject())
        return ReportBadArrayType(cx);
    if (!v.toObject().is<SharedTypedArrayObject>())
        return ReportBadArrayType(cx);
    viewp.set(&v.toObject().as<SharedTypedArrayObject>());
    return true;
}
예제 #4
0
bool
SavedStacks::insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandle<SavedFrame*> frame)
{
    if (iter.done()) {
        frame.set(nullptr);
        return true;
    }

    // Don't report the over-recursion error because if we are blowing the stack
    // here, we already blew the stack in JS, reported it, and we are creating
    // the saved stack for the over-recursion error object. We do this check
    // here, rather than inside saveCurrentStack, because in some cases we will
    // pass the check there, despite later failing the check here (for example,
    // in js/src/jit-test/tests/saved-stacks/bug-1006876-too-much-recursion.js).
    JS_CHECK_RECURSION_DONT_REPORT(cx, return false);

    ScriptFrameIter thisFrame(iter);
    Rooted<SavedFrame*> parentFrame(cx);
    if (!insertFrames(cx, ++iter, &parentFrame))
        return false;

    RootedScript script(cx, thisFrame.script());
    RootedFunction callee(cx, thisFrame.maybeCallee());
    const char *filename = script->filename();
    RootedAtom source(cx, Atomize(cx, filename, strlen(filename)));
    if (!source)
        return false;
    uint32_t column;
    uint32_t line = PCToLineNumber(script, thisFrame.pc(), &column);

    SavedFrame::Lookup lookup(source,
                              line,
                              column,
                              callee ? callee->displayAtom() : nullptr,
                              parentFrame,
                              thisFrame.compartment()->principals);

    frame.set(getOrCreateSavedFrame(cx, lookup));
    return frame.get() != nullptr;
}
예제 #5
0
static bool
CloneModule(JSContext* cx, MutableHandle<AsmJSModuleObject*> moduleObj)
{
    ScopedJSDeletePtr<AsmJSModule> module;
    if (!moduleObj->module().clone(cx, &module))
        return false;

    AsmJSModuleObject* newModuleObj = AsmJSModuleObject::create(cx, &module);
    if (!newModuleObj)
        return false;

    moduleObj.set(newModuleObj);
    return true;
}
예제 #6
0
bool GetRenderTargetProperty( JSContext *cx, Handle<JSObject *> object, Handle<jsid> id, MutableHandle<Value> value )
{
    RootedValue val(cx); JS_IdToValue( cx, id, MutableHandleValue(&val) );
    JSString *propertyString = val.toString(); const char *propertyName=JS_EncodeString(cx, propertyString);   
    //printf("GetRenderTargetProperty: %s\n", propertyName ); 
    
    RenderTarget *target=(RenderTarget *) JS_GetPrivate( object );

    if ( !strcmp( propertyName, "w" ) ) {
        value.set( INT_TO_JSVAL( target->w ) );
    } else   
    if ( !strcmp( propertyName, "h" ) ) {
        value.set( INT_TO_JSVAL( target->h ) );
    } else
    if ( !strcmp( propertyName, "autoResize" ) ) {
        value.set( BOOLEAN_TO_JSVAL( target->autoResize ) );
    } else
    if ( !strcmp( propertyName, "main" ) ) {
        value.set( BOOLEAN_TO_JSVAL( target->main ) );
    }  

    return true;    
}
예제 #7
0
static bool
DecodeMemory(JSContext* cx, Decoder& d, ModuleGenerator& mg, MutableHandle<ArrayBufferObject*> heap)
{
    uint32_t sectionStart;
    if (!d.startSection(MemoryId, &sectionStart))
        return Fail(cx, d, "failed to start section");
    if (sectionStart == Decoder::NotStarted)
        return true;

    uint32_t initialSizePages;
    if (!d.readVarU32(&initialSizePages))
        return Fail(cx, d, "expected initial memory size");

    CheckedInt<int32_t> initialSize = initialSizePages;
    initialSize *= PageSize;
    if (!initialSize.isValid())
        return Fail(cx, d, "initial memory size too big");

    uint32_t maxSizePages;
    if (!d.readVarU32(&maxSizePages))
        return Fail(cx, d, "expected initial memory size");

    CheckedInt<int32_t> maxSize = maxSizePages;
    maxSize *= PageSize;
    if (!maxSize.isValid())
        return Fail(cx, d, "initial memory size too big");

    uint8_t exported;
    if (!d.readFixedU8(&exported))
        return Fail(cx, d, "expected exported byte");

    if (exported) {
        UniqueChars fieldName = DuplicateString("memory");
        if (!fieldName || !mg.addMemoryExport(Move(fieldName)))
            return false;
    }

    if (!d.finishSection(sectionStart))
        return Fail(cx, d, "memory section byte size mismatch");

    bool signalsForOOB = CompileArgs(cx).useSignalHandlersForOOB;
    heap.set(ArrayBufferObject::createForWasm(cx, initialSize.value(), signalsForOOB));
    if (!heap)
        return false;

    mg.initHeapUsage(HeapUsage::Unshared);
    return true;
}
예제 #8
0
static bool
DecodeMemorySection(JSContext* cx, Decoder& d, ModuleGenerator& mg,
                    MutableHandle<ArrayBufferObject*> heap)
{
    if (!d.readCStringIf(MemoryLabel))
        return true;

    uint32_t sectionStart;
    if (!d.startSection(&sectionStart))
        return Fail(cx, d, "expected memory section byte size");

    if (!d.readCStringIf(InitialLabel))
        return Fail(cx, d, "expected memory section initial field");

    uint32_t initialHeapSize;
    if (!d.readVarU32(&initialHeapSize))
        return Fail(cx, d, "expected initial memory size");

    if (initialHeapSize < PageSize || initialHeapSize % PageSize != 0)
        return Fail(cx, d, "initial memory size not a multiple of 0x10000");

    if (initialHeapSize > INT32_MAX)
        return Fail(cx, d, "initial memory size too big");

    if (!d.readCStringIf(EndLabel))
        return Fail(cx, d, "expected end field of memory section");

    if (!d.finishSection(sectionStart))
        return Fail(cx, d, "memory section byte size mismatch");

    bool signalsForOOB = CompileArgs(cx).useSignalHandlersForOOB;
    heap.set(ArrayBufferObject::createForWasm(cx, initialHeapSize, signalsForOOB));
    if (!heap)
        return false;

    mg.initHeapUsage(HeapUsage::Unshared);
    return true;
}
예제 #9
0
bool
js::GetProperty(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
                Handle<PropertyId> pid, unsigned resolveFlags, MutableHandle<Value> vp)
{
    NEW_OBJECT_REPRESENTATION_ONLY();

    MOZ_ASSERT(receiver);

    Rooted<ObjectImpl*> current(cx, obj);

    do {
        MOZ_ASSERT(obj);

        if (Downcast(current)->isProxy()) {
            MOZ_NOT_REACHED("NYI: proxy [[GetP]]");
            return false;
        }

        PropDesc desc;
        PropDesc::AutoRooter rootDesc(cx, &desc);
        if (!GetOwnProperty(cx, current, pid, resolveFlags, &desc))
            return false;

        /* No property?  Recur or bottom out. */
        if (desc.isUndefined()) {
            current = current->getProto();
            if (current)
                continue;

            vp.setUndefined();
            return true;
        }

        /* If it's a data property, return the value. */
        if (desc.isDataDescriptor()) {
            vp.set(desc.value());
            return true;
        }

        /* If it's an accessor property, call its [[Get]] with the receiver. */
        if (desc.isAccessorDescriptor()) {
            Rooted<Value> get(cx, desc.getterValue());
            if (get.isUndefined()) {
                vp.setUndefined();
                return true;
            }

            InvokeArgsGuard args;
            if (!cx->stack.pushInvokeArgs(cx, 0, &args))
                return false;

            args.setCallee(get);
            args.setThis(ObjectValue(*receiver));

            bool ok = Invoke(cx, args);
            vp.set(args.rval());
            return ok;
        }

        /* Otherwise it's a PropertyOp-based property.  XXX handle this! */
        MOZ_NOT_REACHED("NYI: handle PropertyOp'd properties here");
        return false;
    } while (false);

    MOZ_NOT_REACHED("buggy control flow");
    return false;
}
// ES6 (5 April 2014) 9.5.5 Proxy.[[GetOwnProperty]](P)
bool
ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                                     MutableHandle<PropertyDescriptor> desc) const
{
    // step 2
    RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));

    // step 3
    if (!handler) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
        return false;
    }

    // step 4
    RootedObject target(cx, proxy->as<ProxyObject>().target());

    // step 5-6
    RootedValue trap(cx);
    if (!GetProperty(cx, handler, handler, cx->names().getOwnPropertyDescriptor, &trap))
        return false;

    // step 7
    if (trap.isUndefined())
        return GetOwnPropertyDescriptor(cx, target, id, desc);

    // step 8-9
    RootedValue propKey(cx);
    if (!IdToStringOrSymbol(cx, id, &propKey))
        return false;

    Value argv[] = {
        ObjectValue(*target),
        propKey
    };
    RootedValue trapResult(cx);
    if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
        return false;

    // step 10
    if (!trapResult.isUndefined() && !trapResult.isObject()) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_GETOWN_OBJORUNDEF);
        return false;
    }

    //step 11-12
    Rooted<PropertyDescriptor> targetDesc(cx);
    if (!GetOwnPropertyDescriptor(cx, target, id, &targetDesc))
        return false;

    // step 13
    if (trapResult.isUndefined()) {
        // substep a
        if (!targetDesc.object()) {
            desc.object().set(nullptr);
            return true;
        }

        // substep b
        if (!targetDesc.configurable()) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NC_AS_NE);
            return false;
        }

        // substep c-e
        bool extensibleTarget;
        if (!IsExtensible(cx, target, &extensibleTarget))
            return false;
        if (!extensibleTarget) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REPORT_E_AS_NE);
            return false;
        }

        // substep f
        desc.object().set(nullptr);
        return true;
    }

    // step 14-15
    bool extensibleTarget;
    if (!IsExtensible(cx, target, &extensibleTarget))
        return false;

    // step 16-17
    Rooted<PropertyDescriptor> resultDesc(cx);
    if (!ToPropertyDescriptor(cx, trapResult, true, &resultDesc))
        return false;

    // step 18
    CompletePropertyDescriptor(&resultDesc);

    // step 19
    bool valid;
    if (!ValidatePropertyDescriptor(cx, extensibleTarget, resultDesc, targetDesc, &valid))
        return false;

    // step 20
    if (!valid) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REPORT_INVALID);
        return false;
    }

    // step 21
    if (!resultDesc.configurable()) {
        if (!targetDesc.object()) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NE_AS_NC);
            return false;
        }

        if (targetDesc.configurable()) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REPORT_C_AS_NC);
            return false;
        }
    }

    // step 22
    desc.set(resultDesc);
    desc.object().set(proxy);
    return true;
}
예제 #11
0
static bool
DecodeModule(JSContext* cx, UniqueChars filename, const uint8_t* bytes, uint32_t length,
             ImportNameVector* importNames, ExportMap* exportMap,
             MutableHandle<WasmModuleObject*> moduleObj)
{
    Decoder d(bytes, bytes + length);

    uint32_t u32;
    if (!d.readU32(&u32) || u32 != MagicNumber)
        return Fail(cx, d, "failed to match magic number");

    if (!d.readU32(&u32) || u32 != EncodingVersion)
        return Fail(cx, d, "failed to match binary version");

    UniqueModuleGeneratorData init = MakeUnique<ModuleGeneratorData>();
    if (!init)
        return false;

    if (!DecodeSignatureSection(cx, d, init.get()))
        return false;

    if (!DecodeDeclarationSection(cx, d, init.get()))
        return false;

    if (!DecodeImportSection(cx, d, init.get(), importNames))
        return false;

    ModuleGenerator mg(cx);
    if (!mg.init(Move(init)))
        return false;

    if (!DecodeExportsSection(cx, d, mg, exportMap))
        return false;

    HeapUsage heapUsage = HeapUsage::None;

    if (!DecodeCodeSection(cx, d, mg))
        return false;

    CacheableCharsVector funcNames;

    while (!d.readCStringIf(EndSection)) {
        if (!DecodeUnknownSection(cx, d))
            return false;
    }

    if (!d.done())
        return Fail(cx, d, "failed to consume all bytes of module");

    UniqueModuleData module;
    UniqueStaticLinkData link;
    SlowFunctionVector slowFuncs(cx);
    if (!mg.finish(heapUsage, Move(filename), Move(funcNames), &module, &link, &slowFuncs))
        return false;

    moduleObj.set(WasmModuleObject::create(cx));
    if (!moduleObj)
        return false;

    if (!moduleObj->init(cx->new_<Module>(Move(module))))
        return false;

    return moduleObj->module().staticallyLink(cx, *link);
}
예제 #12
0
static bool
DecodeModule(JSContext* cx, UniqueChars file, const uint8_t* bytes, uint32_t length,
             ImportNameVector* importNames, UniqueExportMap* exportMap,
             MutableHandle<ArrayBufferObject*> heap, MutableHandle<WasmModuleObject*> moduleObj)
{
    Decoder d(bytes, bytes + length);

    uint32_t u32;
    if (!d.readFixedU32(&u32) || u32 != MagicNumber)
        return Fail(cx, d, "failed to match magic number");

    if (!d.readFixedU32(&u32) || u32 != EncodingVersion)
        return Fail(cx, d, "failed to match binary version");

    UniqueModuleGeneratorData init = js::MakeUnique<ModuleGeneratorData>(cx);
    if (!init)
        return false;

    if (!DecodeSignatures(cx, d, init.get()))
        return false;

    if (!DecodeImportTable(cx, d, init.get(), importNames))
        return false;

    if (!DecodeFunctionSignatures(cx, d, init.get()))
        return false;

    if (!DecodeFunctionTable(cx, d, init.get()))
        return false;

    ModuleGenerator mg(cx);
    if (!mg.init(Move(init), Move(file)))
        return false;

    if (!DecodeMemory(cx, d, mg, heap))
        return false;

    if (!DecodeExportTable(cx, d, mg))
        return false;

    if (!DecodeFunctionBodies(cx, d, mg))
        return false;

    if (!DecodeDataSegments(cx, d, heap))
        return false;

    CacheableCharsVector funcNames;

    while (!d.done()) {
        if (!d.skipSection())
            return Fail(cx, d, "failed to skip unknown section at end");
    }

    UniqueModuleData module;
    UniqueStaticLinkData staticLink;
    SlowFunctionVector slowFuncs(cx);
    if (!mg.finish(Move(funcNames), &module, &staticLink, exportMap, &slowFuncs))
        return false;

    moduleObj.set(WasmModuleObject::create(cx));
    if (!moduleObj)
        return false;

    if (!moduleObj->init(cx->new_<Module>(Move(module))))
        return false;

    return moduleObj->module().staticallyLink(cx, *staticLink);
}
예제 #13
0
// ES8 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93 9.5.5 Proxy.[[GetOwnProperty]](P)
bool
ScriptedProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                               MutableHandle<PropertyDescriptor> desc) const
{
    // Steps 2-4.
    RootedObject handler(cx, ScriptedProxyHandler::handlerObject(proxy));
    if (!handler) {
        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
        return false;
    }

    // Step 5.
    RootedObject target(cx, proxy->as<ProxyObject>().target());
    MOZ_ASSERT(target);

    // Step 6.
    RootedValue trap(cx);
    if (!GetProxyTrap(cx, handler, cx->names().getOwnPropertyDescriptor, &trap))
        return false;

    // Step 7.
    if (trap.isUndefined())
        return GetOwnPropertyDescriptor(cx, target, id, desc);

    // Step 8.
    RootedValue propKey(cx);
    if (!IdToStringOrSymbol(cx, id, &propKey))
        return false;

    RootedValue trapResult(cx);
    RootedValue targetVal(cx, ObjectValue(*target));
    if (!Call(cx, trap, handler, targetVal, propKey, &trapResult))
        return false;

    // Step 9.
    if (!trapResult.isUndefined() && !trapResult.isObject())
        return js::Throw(cx, id, JSMSG_PROXY_GETOWN_OBJORUNDEF);

    // Step 10.
    Rooted<PropertyDescriptor> targetDesc(cx);
    if (!GetOwnPropertyDescriptor(cx, target, id, &targetDesc))
        return false;

    // Step 11.
    if (trapResult.isUndefined()) {
        // Step 11a.
        if (!targetDesc.object()) {
            desc.object().set(nullptr);
            return true;
        }

        // Step 11b.
        if (!targetDesc.configurable())
            return js::Throw(cx, id, JSMSG_CANT_REPORT_NC_AS_NE);

        // Steps 11c-d.
        bool extensibleTarget;
        if (!IsExtensible(cx, target, &extensibleTarget))
            return false;

        // Step 11e.
        if (!extensibleTarget)
            return js::Throw(cx, id, JSMSG_CANT_REPORT_E_AS_NE);

        // Step 11f.
        desc.object().set(nullptr);
        return true;
    }

    // Step 12.
    bool extensibleTarget;
    if (!IsExtensible(cx, target, &extensibleTarget))
        return false;

    // Step 13.
    Rooted<PropertyDescriptor> resultDesc(cx);
    if (!ToPropertyDescriptor(cx, trapResult, true, &resultDesc))
        return false;

    // Step 14.
    CompletePropertyDescriptor(&resultDesc);

    // Step 15.
    const char* errorDetails = nullptr;
    if (!IsCompatiblePropertyDescriptor(cx, extensibleTarget, resultDesc, targetDesc,
                                        &errorDetails))
        return false;

    // Step 16.
    if (errorDetails)
        return js::Throw(cx, id, JSMSG_CANT_REPORT_INVALID, errorDetails);

    // Step 17.
    if (!resultDesc.configurable()) {
        if (!targetDesc.object())
            return js::Throw(cx, id, JSMSG_CANT_REPORT_NE_AS_NC);

        if (targetDesc.configurable())
            return js::Throw(cx, id, JSMSG_CANT_REPORT_C_AS_NC);
    }

    // Step 18.
    desc.set(resultDesc);
    desc.object().set(proxy);
    return true;
}