Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Create dummy jsscript
Browse files Browse the repository at this point in the history
  • Loading branch information
khyperia committed Aug 8, 2019
1 parent da02bce commit 67240c6
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 59 deletions.
118 changes: 118 additions & 0 deletions js/src/frontend/Frontend2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "frontend/Frontend2.h"

#include "gc/AllocKind.h"

using JS::RootedScript;
using mozilla::Utf8Unit;

using namespace js::gc;
using namespace js::frontend;
using namespace js;

bool InitScript(JSContext* cx, HandleScript script,
HandleFunction canoicalFunction) {
uint32_t natoms = 0;
if (!script->createScriptData(cx, natoms)) {
return false;
}

uint32_t numGCThings = 1;
if (!JSScript::createPrivateScriptData(cx, script, numGCThings)) {
return false;
}

RootedScope enclosing(cx, &cx->global()->emptyGlobalScope());
Scope* functionProtoScope = FunctionScope::create(
cx, nullptr, false, false, canoicalFunction, enclosing);
if (!functionProtoScope) {
return false;
}

mozilla::Span<JS::GCCellPtr> gcthings = script->data_->gcthings();
gcthings[0] = JS::GCCellPtr(functionProtoScope);

uint32_t codeLength = 1;
uint32_t noteLength = 2;
uint32_t numResumeOffsets = 0;
uint32_t numScopeNotes = 0;
uint32_t numTryNotes = 0;
if (!script->createImmutableScriptData(cx, codeLength, noteLength,
numResumeOffsets, numScopeNotes,
numTryNotes)) {
return false;
}

jsbytecode* code = script->immutableScriptData()->code();
code[0] = JSOP_RETRVAL;

jssrcnote* notes = script->immutableScriptData()->notes();
notes[0] = SRC_NULL;
notes[1] = SRC_NULL;

return script->shareScriptData(cx);
}

bool Create(JSContext* cx, const char* bytes, size_t length) {
JS::CompileOptions options(cx);
options.setIntroductionType("js shell interactive")
.setIsRunOnce(true)
.setFileAndLine("typein", 1);

JS::SourceText<Utf8Unit> srcBuf;
if (!srcBuf.init(cx, bytes, length, JS::SourceOwnership::Borrowed)) {
return false;
}

ScriptSource* ss = cx->new_<ScriptSource>();
if (!ss) {
return false;
}

ScriptSourceHolder ssHolder(ss);

if (!ss->initFromOptions(cx, options, mozilla::Nothing())) {
return false;
}

RootedScriptSourceObject sso(cx, ScriptSourceObject::create(cx, ss));
if (!sso) {
return false;
}

if (!ScriptSourceObject::initFromOptions(cx, sso, options)) {
return false;
}

RootedObject proto(cx);
if (!GetFunctionPrototype(cx, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, &proto)) {
return false;
}

Rooted<JSAtom*> name(cx, cx->names().name);
FunctionFlags flags;
flags.setInterpreted();
RootedFunction canoicalFunction(
cx, NewFunctionWithProto(cx, nullptr, 0, flags, nullptr, name, proto,
AllocKind::FUNCTION, TenuredObject));

RootedScript script(cx,
JSScript::Create(cx, options, sso, 0, length, 0, length));

if (!InitScript(cx, script, nullptr)) {
return false;
}

RootedValue result(cx);
if (!JS_ExecuteScript(cx, script, &result)) {
return false;
}

return true;
}
22 changes: 22 additions & 0 deletions js/src/frontend/Frontend2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef frontend_Frontend2_h
#define frontend_Frontend2_h

#include "js/CompilationAndEvaluation.h"
#include "js/SourceText.h"
#include "vm/GlobalObject.h"
#include "vm/JSAtom.h"
#include "vm/JSContext.h"
#include "vm/JSFunction.h"
#include "vm/JSScript.h"

bool InitScript(JSContext* cx, JS::HandleScript script,
JS::HandleFunction functionProto);
bool Create(JSContext* cx, const char* bytes, size_t length);

#endif /* frontend_Frontend2_h */
1 change: 1 addition & 0 deletions js/src/frontend/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ UNIFIED_SOURCES += [
'ForInEmitter.cpp',
'ForOfEmitter.cpp',
'ForOfLoopControl.cpp',
'Frontend2.cpp',
'FunctionEmitter.cpp',
'IfEmitter.cpp',
'JumpList.cpp',
Expand Down
10 changes: 8 additions & 2 deletions js/src/shell/js.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#if defined(JS_BUILD_BINAST)
# include "frontend/BinASTParser.h"
#endif // defined(JS_BUILD_BINAST)
#include "frontend/Frontend2.h"
#include "frontend/ModuleSharedContext.h"
#include "frontend/Parser.h"
#include "gc/PublicIterators.h"
Expand Down Expand Up @@ -10049,6 +10050,10 @@ static MOZ_MUST_USE bool ProcessArgs(JSContext* cx, OptionParser* op) {
binASTPaths = op->getMultiStringOption('B');
#endif // JS_BUILD_BINAST

if (op->getBoolOption("rust-frontend")) {
return Create(cx, "x", 1);
}

if (filePaths.empty() && utf8FilePaths.empty() && codeChunks.empty() &&
modulePaths.empty() && binASTPaths.empty() &&
!op->getStringArg("script")) {
Expand Down Expand Up @@ -11152,7 +11157,8 @@ int main(int argc, char** argv, char** envp) {
"Suppress crash minidumps") ||
!op.addBoolOption('\0', "wasm-compile-and-serialize",
"Compile the wasm bytecode from stdin and serialize "
"the results to stdout")) {
"the results to stdout") ||
!op.addBoolOption('\0', "rust-frontend", "Use Rust frontend")) {
return EXIT_FAILURE;
}

Expand Down Expand Up @@ -11255,7 +11261,7 @@ int main(int argc, char** argv, char** envp) {
cpuCount = op.getIntOption("thread-count"); // Legacy name
}
if (cpuCount >= 0 && !SetFakeCPUCount(cpuCount)) {
return 1;
return 1;
}

size_t nurseryBytes = JS::DefaultNurseryBytes;
Expand Down
59 changes: 6 additions & 53 deletions js/src/vm/JSScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1018,9 +1018,8 @@ XDRResult js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
// which are not normally present. Globals with instrumentation enabled must
// compile scripts via the bytecode emitter, which will insert these
// instructions.
if (xdr->hasOptions()
? !!xdr->options().instrumentationKinds
: !!cx->global()->getInstrumentationHolder()) {
if (xdr->hasOptions() ? !!xdr->options().instrumentationKinds
: !!cx->global()->getInstrumentationHolder()) {
return xdr->fail(JS::TranscodeResult_Failure);
}

Expand Down Expand Up @@ -3972,51 +3971,6 @@ bool JSScript::createPrivateScriptData(JSContext* cx, HandleScript script,
return true;
}

/* static */
bool JSScript::initFunctionPrototype(JSContext* cx, HandleScript script,
HandleFunction functionProto) {
uint32_t numGCThings = 1;
if (!createPrivateScriptData(cx, script, numGCThings)) {
return false;
}

RootedScope enclosing(cx, &cx->global()->emptyGlobalScope());
Scope* functionProtoScope = FunctionScope::create(cx, nullptr, false, false,
functionProto, enclosing);
if (!functionProtoScope) {
return false;
}

mozilla::Span<JS::GCCellPtr> gcthings = script->data_->gcthings();
gcthings[0] = JS::GCCellPtr(functionProtoScope);

uint32_t codeLength = 1;
uint32_t noteLength = 3;
uint32_t numResumeOffsets = 0;
uint32_t numScopeNotes = 0;
uint32_t numTryNotes = 0;
if (!script->createImmutableScriptData(cx, codeLength, noteLength,
numResumeOffsets, numScopeNotes,
numTryNotes)) {
return false;
}

jsbytecode* code = script->immutableScriptData()->code();
code[0] = JSOP_RETRVAL;

jssrcnote* notes = script->immutableScriptData()->notes();
notes[0] = SRC_NULL;
notes[1] = SRC_NULL;
notes[2] = SRC_NULL;

uint32_t numAtoms = 0;
if (!script->createScriptData(cx, numAtoms)) {
return false;
}

return script->shareScriptData(cx);
}

static void InitAtomMap(frontend::AtomIndexMap& indices, GCPtrAtom* atoms) {
for (frontend::AtomIndexMap::Range r = indices.all(); !r.empty();
r.popFront()) {
Expand Down Expand Up @@ -4541,9 +4495,8 @@ static JSObject* CloneInnerInterpretedFunction(
cx->markAtom(atom);
}
RootedFunction clone(
cx, NewFunctionWithProto(cx, nullptr, srcFun->nargs(),
flags, nullptr, atom, cloneProto,
allocKind, TenuredObject));
cx, NewFunctionWithProto(cx, nullptr, srcFun->nargs(), flags, nullptr,
atom, cloneProto, allocKind, TenuredObject));
if (!clone) {
return nullptr;
}
Expand Down Expand Up @@ -5384,8 +5337,8 @@ LazyScript* LazyScript::CreateForXDR(
uint32_t toStringEnd, uint32_t lineno, uint32_t column) {
LazyScript* res = LazyScript::CreateRaw(
cx, numClosedOverBindings, numInnerFunctions, fun, sourceObject,
immutableFlags, sourceStart, sourceEnd, toStringStart, toStringEnd, lineno,
column);
immutableFlags, sourceStart, sourceEnd, toStringStart, toStringEnd,
lineno, column);
if (!res) {
return nullptr;
}
Expand Down
7 changes: 3 additions & 4 deletions js/src/vm/JSScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -2225,6 +2225,9 @@ class JSScript : public js::BaseScript {
js::HandleScriptSourceObject sourceObject,
js::MutableHandle<JS::GCVector<js::Scope*>> scopes);

friend bool InitScript(JSContext* cx, JS::HandleScript script,
JS::HandleFunction functionProto);

private:
JSScript(JS::Realm* realm, uint8_t* stubEntry,
js::HandleScriptSourceObject sourceObject, uint32_t sourceStart,
Expand Down Expand Up @@ -2258,10 +2261,6 @@ class JSScript : public js::BaseScript {
static bool fullyInitFromEmitter(JSContext* cx, js::HandleScript script,
js::frontend::BytecodeEmitter* bce);

// Initialize the Function.prototype script.
static bool initFunctionPrototype(JSContext* cx, js::HandleScript script,
JS::HandleFunction functionProto);

#ifdef DEBUG
private:
// Assert that jump targets are within the code array of the script.
Expand Down

0 comments on commit 67240c6

Please sign in to comment.